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

를 컴파일 오류를 범 :

item.q의 개구 브레이스 지칭
q.go:11:12: error: expected ';' or '}' or newline 
q.go:12:12: error: expected ';' or '}' or newline

[N] = q 및 다음 줄.

대신에 간단한 문자열로 잘 작동하므로 조각을 잘못 사용하고있는 것이 확실합니다. 그러나이를 수정하는 방법을 모르겠습니다.

편집 : Pat Notz의 조언에 따라 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) 
} 

답변

0

슬라이스를 사용하여 발생한 문제를 StringVector에 위임하여 문제를 해결했습니다. 문자열 조각을 사용하는 초기 구현을 수정하여 유효한 작동중인 프로그램이되었습니다.

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

유형 질문은 문자열 배열의 슬라이스 인 두 개의 요소 인 q와 a가있는 구조체입니다. 슬라이스는 암시 적으로 슬라이스를 시작하는 배열 요소에 대한 포인터, 슬라이스의 길이 및 슬라이스의 용량을 포함합니다.

var q Question 

는 질문 구조체에 대한 스토리지를 할당, Q를 선언하고 초기화 구조체 필드 (조각 전분기 및 품질 보증)를 제로로 슬라이스 포인터가 전무 즉, 그리고 슬라이스 LEN()와 캡() 함수는 0을 반환 . 문자열 배열에는 저장소가 할당되지 않습니다. 우리는 별도로해야합니다.

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

슬라이스는 단순히 배열로 보기이다 : 다음은 작업 코드입니다. 코드 스 니펫을 기반으로 container/vector 패키지의 StringVector을 사용하려고합니다. 동적 크기의 배열을위한 유일한 선택입니다. 내장 된 배열의 크기는 고정되어 있습니다. 저장하려는 요소의 수를 미리 알고있는 경우에도 잘 작동합니다.

+0

감사합니다! – smskelley

1

문제는 추가 방법 - 당신은 조각의 요소를 할당 할 때, 당신은 대신 '='를 사용한다 '='

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

: = 연산자는 선언에만 사용됩니다 새 변수

+0

이 메서드를 사용하여 컴파일하는 동안 런타임에 다음을 throw합니다. 인덱스 범위를 벗어남 패닉 중단됨 – smskelley

0

당신은 item.q[n] := q 같이 :=를 사용 야해.

:=은 새 변수에 할당해야 할 때만 사용됩니다. 이 경우

, 당신은 대신 컨테이너/벡터의 조각을 사용하는 것도 좋은 item.q[n] = q

그것을 사용해야합니다. go (1.0.3)는 더 이상 벡터를 지원하지 않습니다.

조각에 항목을 추가하는 더 좋은 방법은 그 들여다 것,

slice = append(slice, new_item_1,item_2,item_3)