2017-08-21 4 views
1

Es könnte eine dumme Frage sein, aber wenn ich versuche, eine [] Byte-Scheibe an eine [][]byte Scheibe anzuhängen, bekomme ich seltsame Ergebnisse.an ein Stück in For-Schleife mit unerwarteten Ergebnissen anfügen

Hier ist mein Code:

func Normalizer(s string) (ss [][]byte) { 

    ss = make([][]byte, 0) 
    // norm 
    var ia norm.Iter 

    ia.InitString(norm.NFC, s) 

    for !ia.Done() { 

     next := ia.Next() 

     fmt.Println(next) 
     // [226 128 139] 
     // [227 128 129] 
     // [39] 
     // [226 128 153] 
     // [46] 
     // [44] 
     // [63] 
     // [33] 
     // [92] 
     // [10] 
     // [226 128 153] 
     // ... 
     ss = append(ss, next) 

    } 
    ia.Done() 


    fmt.Println(ss) 
    return 
} 

Ich erwarte somethin wie folgt aus:

// [[226 128 139] [227 128 129] [39] [226 128 153] [46] [44] [63] [33] [92] [10] [226 128 153]...] 

sondern bekomme ich dies:

// [[226 129 128] [226 129 128] [226] [226 129 128] [226] [226] [226] [226] [226] [226] [226 129 128]...] 

und ich habe keine Ahnung, warum . Hilfe und Erklärung wären willkommen.

Antwort

2

Ein Slice ist eine Struktur mit einem Zeiger auf ein zugrunde liegendes Array, eine Länge und eine Kapazität.

Sie ändern das zugrunde liegende Array, nachdem Sie die Slice-Struktur angefügt haben. ia.Next() wiederverwendet seinen Rückgabepuffer.

Zum Beispiel

package main 

import (
    "fmt" 

    "golang.org/x/text/unicode/norm" 
) 

func Normalizer(s string) (ss [][]byte) { 
    ss = make([][]byte, 0) 
    var ia norm.Iter 
    ia.InitString(norm.NFC, s) 
    for !ia.Done() { 
     next := ia.Next() 
     fmt.Println(string(next), &next[0]) 
     ss = append(ss, next) 
    } 
    fmt.Println() 
    for i := range ss { 
     fmt.Println(string(ss[i]), &ss[i][0]) 
    } 
    fmt.Println() 
    return 
} 

func main() { 
    ss := Normalizer("abc") 
    fmt.Printf("%s\n", ss) 
} 

Output:

a 0xc420092228 
b 0xc420092228 
c 0xc420092228 

c 0xc420092228 
c 0xc420092228 
c 0xc420092228 

[c c c] 

eine Kopie eines struct slice Ersetzen

next := ia.Next() 

mit einem neuen Scheibe struct mit einem neuen zugrunde liegenden Array

next := append([]byte(nil), ia.Next()...) 

Zum Beispiel

package main 

import (
    "fmt" 

    "golang.org/x/text/unicode/norm" 
) 

func Normalizer(s string) (ss [][]byte) { 
    ss = make([][]byte, 0) 
    var ia norm.Iter 
    ia.InitString(norm.NFC, s) 
    for !ia.Done() { 
     next := append([]byte(nil), ia.Next()...) 
     fmt.Println(string(next), &next[0]) 
     ss = append(ss, next) 
    } 
    fmt.Println() 
    for i := range ss { 
     fmt.Println(string(ss[i]), &ss[i][0]) 
    } 
    fmt.Println() 
    return 
} 

func main() { 
    ss := Normalizer("abc") 
    fmt.Printf("%s\n", ss) 
} 

Ausgang:

a 0xc4200120d0 
b 0xc4200120e8 
c 0xc420012108 

a 0xc4200120d0 
b 0xc4200120e8 
c 0xc420012108 

[a b c] 

Referenzen:

Slice types

Go Slices: usage and internals

Arrays, slices (and strings): The mechanics of 'append'

+0

Es ist golang in utf-8 String Normalisierung lib bauen. https://godoc.org/golang.org/x/text/unicode/norm#Iter TL: DR; Es gibt '[] byte' – Lupus

+0

Vielen Dank für zusätzlichen Aufwand :) – Lupus

Verwandte Themen