Question

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

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)
}
Was it helpful?

Solution

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

OTHER TIPS

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 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)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top