2012-10-30 9 views
75

ich versucht habe:eine konstante Array

const ascii = "abcdefghijklmnopqrstuvwxyz" 
const letter_goodness []float32 = { .0817,.0149,.0278,.0425,.1270,.0223,.0202, .0609,.0697,.0015,.0077,.0402,.0241,.0675, .0751,.0193,.0009,.0599,.0633,.0906,.0276, .0098,.0236,.0015,.0197,.0007 } 
const letter_goodness = { .0817,.0149,.0278,.0425,.1270,.0223,.0202, .0609,.0697,.0015,.0077,.0402,.0241,.0675, .0751,.0193,.0009,.0599,.0633,.0906,.0276, .0098,.0236,.0015,.0197,.0007 } 
const letter_goodness = []float32 { .0817,.0149,.0278,.0425,.1270,.0223,.0202, .0609,.0697,.0015,.0077,.0402,.0241,.0675, .0751,.0193,.0009,.0599,.0633,.0906,.0276, .0098,.0236,.0015,.0197,.0007 } 

Zuerst Deklaration und Initialisierung funktioniert gut, aber die zweite, dritte und vierte nicht funktionieren. Wie kann ich const Array von Floats deklarieren und initialisieren?

Antwort

109

Ein Array ist von Natur aus nicht unveränderbar; Sie können es nicht konstant machen.

Der nächste kann man bekommt, ist:

var letter_goodness = [...]float32 {.0817, .0149, .0278, .0425, .1270, .0223, .0202, .0609, .0697, .0015, .0077, .0402, .0241, .0675, .0751, .0193, .0009, .0599, .0633, .0906, .0276, .0098, .0236, .0015, .0197, .0007 } 
+71

Nur zur Klarstellung: die '[...] T' Syntax ist Zucker für' [123] T'. Es erstellt ein Array fester Größe, aber der Compiler kann herausfinden, wie viele Elemente darin enthalten sind. – jimt

+3

Ich nehme an, dass das Erlauben konstanter Arrays Aktualisierungen des Typsystems erfordern würde. Andernfalls, wenn Sie eine Funktion 'f (xs [5] int) definieren' würden Sie nicht wissen, ob das übergebene Array konstant oder veränderlich war. –

+0

tks, Ich habe Probleme, wenn ich versuche, strings.Join 'kann nicht verwenden constants.FilesRequired (type [4] string) als type [] Zeichenfolge im Argument strings.Join' –

34

Von Effective Go:

Konstanten in Go sind nur, dass-Konstante. Sie werden zur Kompilierzeit erstellt, auch wenn sie in Funktionen als Locals definiert sind, und können nur Zahlen, Strings oder Boolesche Werte sein. Aufgrund der Einschränkung der Kompilierungszeit müssen die Ausdrücke, die sie definieren, konstante Ausdrücke sein, die vom Compiler ausgewertet werden können. Zum Beispiel ist 1 < < 3 ein konstanter Ausdruck, während math.Sin (math.Pi/4) nicht, weil der Funktionsaufruf zu math.Sin zur Laufzeit auftreten muss.

Scheiben und Arrays werden immer während der Laufzeit ausgewertet:

var TestSlice = []float32 {.03, .02} 
var TestArray = [2]float32 {.03, .02} 
var TestArray2 = [...]float32 {.03, .02} 

[...] der Compiler sagt selbst die Länge des Arrays, um herauszufinden. Scheiben umhüllen Arrays und sind in den meisten Fällen einfacher zu bearbeiten. Stattdessen Konstanten nur für die Verwendung der Variablen unaccessible zu anderen Paketen, indem Sie einen Kleinbuchstaben Anfangsbuchstaben mit:

var ThisIsPublic = [2]float32 {.03, .02} 
var thisIsPrivate = [2]float32 {.03, .02} 

thisIsPrivate ist nur im Paket definiert wird. Wenn Sie Lesezugriff von außen benötigen, können Sie eine einfache Getter-Funktion schreiben (siehe Getters in golang).

+0

Der Beispielcode "use" ist ungültig Go: http://play.golang.org/p/JUsLIsIwkW – zzzz

+0

Es tut mir leid, Sie haben Recht. Meine erste Antwort war völlig falsch. Diese bearbeitete Antwort sollte jetzt mehr Hilfe bieten. – fasmat

9

In Go gibt es keine Array-Konstante.

Zitiert aus der Go Language Specification: Constants:

Es gibt booleschen Konstanten, rune Konstanten ganzzahlige Konstanten, Gleitkommakonstanten, komplexe Konstanten und String-Konstanten. Rune-, Integer-, Gleitkomma- und komplexe Konstanten werden zusammen als numerische Konstanten bezeichnet.

A Constant expression (die eine Konstante zu initialisieren verwendet wird) kann nur constant Operanden enthalten und werden zum Zeitpunkt der Kompilierung ausgewertet.

Die Spezifikation listet die verschiedenen Arten von Konstanten auf. Beachten Sie, dass Sie Konstanten mit constant expressions von Typen mit einem der zulässigen Typen als underlying type erstellen und initialisieren können.Zum Beispiel das gilt:

func main() { 
    type Myint int 
    const i1 Myint = 1 
    const i2 = Myint(2) 
    fmt.Printf("%T %v\n", i1, i1) 
    fmt.Printf("%T %v\n", i2, i2) 
} 

Output (versuchen Sie es auf den Go Playground):

main.Myint 1 
main.Myint 2 

Wenn Sie einen Array benötigen, kann es nur eine Variable sein, aber keine Konstante.

Ich empfehle diese großen Blog Artikel über Konstanten: Constants

+0

was dann, wenn ein Container mit konstanter Größe benötigt wird? –

+0

@Atomic_alarm Können Sie bitte erläutern? – icza

+0

Existiert ob im Golang Analog C-Array? –

1

Wie andere erwähnt haben, gibt es keine offizielle Go für dieses Konstrukt. Das nächste, was ich mir vorstellen kann, wäre eine Funktion, die eine Scheibe zurückgibt. Auf diese Weise können Sie garantieren, dass niemand die Elemente der ursprünglichen Scheibe manipuliert (da sie in das Array "hart-codiert" ist).

ich Ihre Scheibe verkürzt haben, um es ... kürzer ...:

func GetLetterGoodness() []float32 { 
    return [...]float32 { .0817,.0149,.0278,.0425,.1270,.0223 } 
} 
+0

das klingt wie der beste Weg zu gehen, aber der func Rückgabetyp nicht übereinstimmt. verwenden 'kann nicht [6] Stringliteral (Typ [6] string) als Typ [] Zeichenfolge im Gegenzug argument' so' return [] float32 {...} ' – theRemix