2010-02-13 2 views
1

Я чувствую себя немного глупым, так как это должно быть легко, однако я только начал с того, чтобы идти и не могу понять.Использование строкового среза, который должен быть заполнен во время выполнения

package main 

import "fmt" 

type Question struct { 
q []string 
a []string 
} 
func (item *Question) Add(q string, a string) { 
n := len(item.q) 
item.q[n] := q 
item.a[n] := a 
} 

func main() { 
var q Question 
q.Add("A?", "B.") 
}

При компиляции дает ошибку:

q.go:11:12: error: expected ';' or '}' or newline 
q.go:12:12: error: expected ';' or '}' or newline

, который относится к открывающей скобке item.q [п]: = д и следующая строка.

Я уверен, что я неправильно использую фрагменты, так как он отлично работает с простой строкой, но я не уверен, как это исправить.

Редакция: Редактирование: Я использовал его с помощью StringVectors в соответствии с рекомендациями Pat Notz, и он работает хорошо. Ниже приведен рабочий код:

package main 

import (
    fmt "fmt" 
    vector "container/vector" 
) 

type Question struct { 
    q vector.StringVector 
    a vector.StringVector 
} 
func (item *Question) Add(q string, a string) { 
    item.q.Push(q) 
    item.a.Push(a) 
} 
func (item *Question) Print(index int) { 
    if index >= item.q.Len() { 
     return 
    } 
    fmt.Printf("Question: %s\nAnswer: %s\n", item.q.At(index), item.a.At(index)) 
} 
func main() { 
    var q Question 
    q.Add("A?", "B.") 
    q.Print(0) 
} 

ответ

0

Вы обошли проблемы, связанные с использованием срезов, делегируя их в StringVector. Я пересмотрел вашу первоначальную реализацию, которая использовала срезы строк, чтобы стать действующей рабочей программой.

type Question struct { 
    q []string 
    a []string 
} 

Тип Вопрос является структурой, которая состоит из двух элементов, Q и A, которые ломтик массива строк. Срез неявно содержит указатель на элемент массива, который начинает срез, длину среза и емкость среза.

var q Question 

объявляет д, выделение памяти для Вопроса структуры, и инициализирует структуры полей (ломтики Qq и Qa) нулю т.е. ломтика указатели равны нулю, и срез LEN() и крышка() функции возвращают нулевое значение , Для строковых массивов не выделяется память; мы должны сделать это отдельно.

package main 

import "fmt" 

type Question struct { 
    q []string 
    a []string 
} 

func addString(ss []string, s string) []string { 
    if len(ss)+1 > cap(ss) { 
     t := make([]string, len(ss), len(ss)+1) 
     copy(t, ss) 
     ss = t 
    } 
    ss = ss[0 : len(ss)+1] 
    ss[len(ss)-1] = s 
    return ss 
} 

func (item *Question) Add(q string, a string) { 
    item.q = addString(item.q, q) 
    item.a = addString(item.a, a) 
} 

func main() { 
    var q Question 
    q.Add("A?", "B.") 
    fmt.Println("Q&A", q) 
} 
+1

Эта реализация намного хуже, чем использование StringVector из-за всех ненужных распределений и копирования, необходимых для этой реализации. Похоже, что в библиотеке go уже нет векторов. Доступны только списки. – Sahas

+0

вы должны использовать 'append', чтобы добавить что-то в срез эффективно – newacct

2

Кусочек просто вид в массив - не фактический массив. На основе вашего фрагмента кода, я думаю, вы хотите использовать StringVector из пакета container/vector. Это действительно ваш единственный выбор для массивов с динамическим размером. Встроенные массивы имеют фиксированный размер. Они тоже будут хорошо работать, если вы заранее знаете, сколько элементов вы хотите сохранить.

+0

спасибо, я буду смотреть на это! – smskelley

1

Проблема заключается в методе Add - при назначении элемента среза, вы должны использовать «=» вместо «: =»

func (item *Question) Add(q string, a string) { 
n := len(item.q) 
item.q[n] = q 
item.a[n] = a 
} 

оператором: = используется только для объявления новые переменные

+0

, в то время как он компилируется с использованием этого метода, во время выполнения он выбрасывает: индекс за пределами допустимого диапазона panic Aborted – smskelley

0

Вы не должны использовать := как в item.q[n] := q.

:= Используется только при назначении новой переменной.

В этом случае, вы просто должны использовать item.q[n] = q

Сво также лучше использовать ломтики вместо контейнера/вектор. go (1.0.3) больше не поддерживает вектор.

Лучший способ для добавления элемента в срезе является

slice = append(slice, new_item_1,item_2,item_3) 
Смежные вопросы