Использование фрагмента строки, который должен быть заполнен во время выполнения - PullRequest
1 голос
/ 13 февраля 2010

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

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 [n]: = q и следующую строку.

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

edit: я заново реализовал его, используя StringVectors по совету Пэта Нотца, и он работает хорошо. Ниже приведен рабочий код:

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)
}

Ответы [ 4 ]

2 голосов
/ 13 февраля 2010

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

1 голос
/ 13 февраля 2010

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

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

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

0 голосов
/ 16 декабря 2012

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

:= используется только тогда, когда вам нужно присвоить новую переменную.

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

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

Лучший способ добавить элемент к фрагменту -

slice = append(slice, new_item_1,item_2,item_3)
0 голосов
/ 14 февраля 2010

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

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

Тип Question - это структура, которая имеет два элемента, q и a, которые являются кусочками массива строк. Срез неявно содержит указатель на элемент массива, который начинает срез, длину среза и емкость среза.

var q Question

объявляет q, выделяя память для структуры Question, и инициализирует поля структуры (слайсы q.q и q.a) равными нулю, т.е. указатели слайса равны нулю, а функции slice len () и cap () возвращают ноль. Для строковых массивов не выделяется память; нам нужно сделать это отдельно.

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)
}
...