Using a string slice that is to be filled at runtime
I feel a little silly as this should be an easy one, however I just started with go and can't figure it out.
package ma开发者_Go百科in
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.")
}
When Compiling it gives the errors:
q.go:11:12: error: expected ';' or '}' or newline q.go:12:12: error: expected ';' or '}' or newline
that refers to the opening brace of item.q[n] := q and the following line.
I'm certain that I'm using slices incorrectly as it works fine with a simple string instead, but I'm not sure how to fix it.
edit: I have re-implemented it using StringVectors as per Pat Notz's advice and it works well. The following is the working code:
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)
}
A slice is simply a view into an array -- not an actual array. Based on your code snippet I think you want to use StringVector
from the container/vector
package. That's really your only choice for dynamically sized arrays. The built in arrays have a fixed size. They'd work fine too if you know in advance how many elements you want to store.
The problem is in the Add method -- when you assign an element of a slice, you should use '=' instead of ':='
func (item *Question) Add(q string, a string) {
n := len(item.q)
item.q[n] = q
item.a[n] = a
}
The := operator is only used for declaring new variables
You sidestepped the problems you were having using slices by delegating them to StringVector. I've revised your initial implementation, which used string slices, to become a valid, working program.
type Question struct {
q []string
a []string
}
The type Question is a struct which has two elements, q and a, which are slices of an array of strings. A slice implicitly contains a pointer to the element of the array which begins the slice, the length of the slice, and the capacity of the slice.
var q Question
declares q, allocating storage for the Question struct, and initializes the struct fields (slices q.q and q.a) to zero i.e. the slice pointers are nil, and the slice len() and cap() functions return zero. No storage is allocated for string arrays; we need to do that separately.
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)
}
You shouldnt be using :=
as in item.q[n] := q
.
:=
is only used when you have to assign to a new variable.
In this case, you just have to use item.q[n] = q
Its also better to use slices instead of container/vector. go(1.0.3) does not support vector anymore.
A better way to append an item to a slice is
slice = append(slice, new_item_1,item_2,item_3)
精彩评论