2014-12-30 7 views
0

나는 Trie 데이터 구조를 Go Language로 만들려고했지만 어쨌든 참조 문제가 생겼다. 여기있다.Go 언어로 혼동되는 참조 유형

// Package main provides ... 
package main 

import "fmt" 

type RootTrie []Trie 

type Trie struct { 
    subtrie []Trie 
    index byte 
} 

func (trie *Trie) Insert(data string) *Trie { 
    if data != "" { 
     if trie.index == 0 { 
      trie.index = data[0] 
     } 
     if next := trie.containsIndex(data[1:]); next != nil { 
      //Problem Point 
      fmt.Println(string(data[1]), "found follwing", string(data[0])) 
      next.Insert(data[1:]) 
     } else { 
      nt := &Trie{} 
      trie.subtrie = append(trie.subtrie, *nt.Insert(data[1:])) 
     } 
    } 

    return trie 
} 
func (trie *Trie) containsIndex(next string) *Trie { 
    if next != "" { 
     for _, st := range trie.subtrie { 
      if st.index == next[0] { 
       return &st 
      } 
     } 
    } 
    return nil 
} 

func main() { 
    t := &Trie{} 
    t = t.Insert("hanyang") 
    fmt.Println("result:", t) 
    t = t.Insert("hanyKk") 
    fmt.Println("result:", t) 
    t.Insert("hanyK") 
} 

다음과 같은 문제 http://play.golang.org/p/ASSGF5Oe9R는 두 번째 "삽입"내가 다음에 링크 된 트라이 검색을위한 containsIndex 방법을 만들어 //Problem Point

내가 넣어 어디를, 어떻게, 그리고 실제로 잘 검색. 그러나 next 속성을 containsIndex으로 업데이트하면 해당 구조체에 영향을 미치지 않습니다. trie.

내가 이해할 수없는 것은 containsIndex을 반환 할 때 참조 유형을 부여했지만 여전히 행위가 '값 복사 됨'을 좋아했는데 왜 그것이 해당 어머니 구조 (trie)에 영향을 미치지 않는 것입니까?

감사합니다.

+1

- there're 언어 니트를하지만, 문제의 본질을 설명하고 당신이 할 수있는 코드가 엉망이 주변에있다. – twotwotwo

답변

3

문제는 containsIndex입니다. Golang range은 기본적으로 slice의 각 요소를 복사하여이 값의 복사본을 st (예제의 경우)에 할당합니다. 일반적으로 슬라이스의 요소에 대한 참조를 유지하려면 원본 슬라이스와 해당 인덱스를 사용해야합니다. 당신에 경우 방법 containsIndex는 다음과 같이 보일 것입니다 : 나는 -1하지 않는

func (trie *Trie) containsIndex(next string) *Trie { 
    if next != "" { 
     for i, st := range trie.subtrie { 
      if st.index == next[0] { 
       return &trie.subtrie[i] 
      } 
     } 
    } 
    return nil 
} 
+0

인덱스 대신 값을 사용하는 경우에도 성능 차이가 있습니까? –

+0

@EtienneBruines - 아마도. 무시해도 좋을 수도 있고, 컴파일러가 가끔 복사본을 최적화 할 수 있다고 인식한다면 차이가 없을 수도 있습니다. 성능이 중요한 내부 루프에서이 선택 사항을 실행하면 항상 테스트 할 수 있습니다. – twotwotwo

+0

@twotwotwo 답변 해 주셔서 감사합니다. 몇 가지 벤치 마크를 실행했습니다. 복잡하지 않은 경우 성능 차이가 전혀 없습니다. 고맙습니다. @wonsky. https://github.com/EtienneBruines/go-range-performance-analysis –