2014-07-12 14 views
15

Der Typ rune in Go ist defined als "ein Alias ​​für Int32 und entspricht Int32 auf alle Arten. Es wird per Konvention verwendet, um Zeichenwerte von ganzzahligen Werten zu unterscheiden."Warum ist Rune in Golang ein Alias ​​für int32 und nicht für uint32?

Wenn dieser Typ verwendet werden soll, um Zeichenwerte darzustellen, warum haben die Autoren der Go-Sprache nicht uint32 statt int32 verwendet? Wie erwarten sie, dass ein Runenwert in einem Programm behandelt wird, wenn es negativ ist? Der andere ähnliche Typ byte ist ein Alias ​​für uint (und nicht int), was vernünftig ist.

+0

Hinweis: 'byte' ist ein Alias ​​für' uint8', nicht 'uint'. –

Antwort

2

"Golang, Go : what is rune by the way?" erwähnt:

Mit der jüngsten Unicode 6.3 gibt es mehr als 110.000 Symbole definiert. Dies erfordert mindestens 21-Bit-Darstellung jedes Codepunkts, so dass eine Rune wie Int32 ist und viele Bits hat.

Aber in Bezug auf die Überlauf oder einen negativen Wert Probleme, beachten Sie, dass die Umsetzung einiger der Unicode-Funktionen wie unicode.IsGraphic verstehen:

Wir konvertieren uint32 den zusätzlichen Test für negative

zu vermeiden

Code:

const MaxLatin1 = '\u00FF' // maximum Latin-1 value. 

// IsGraphic reports whether the rune is defined as a Graphic by Unicode. 
// Such characters include letters, marks, numbers, punctuation, symbols, and 
// spaces, from categories L, M, N, P, S, Zs. 
func IsGraphic(r rune) bool { 
    // We convert to uint32 to avoid the extra test for negative, 
    // and in the index we convert to uint8 to avoid the range check. 
    if uint32(r) <= MaxLatin1 { 
     return properties[uint8(r)]&pg != 0 
    } 
    return In(r, GraphicRanges...) 
} 

Das vielleicht weil eine Rune soll constant sein (wie in „Go rune type explanation“ erwähnt, wo eine Rune in einem sein könnte int32 oder uint32 oder sogar float32 oder ...: sein konstant Wert autorisiert es in einen der gespeichert werden diese numeric types).

3

Es wird nicht negativ. Momentan gibt es 1.114.112 Codepunkte in Unicode, was weit entfernt von 2.147.483.647 (0x7fffffff) ist - selbst unter Berücksichtigung aller reservierten Blöcke. diese

+1

Danke! Obwohl eine Rune zu diesem Zeitpunkt einen Bereich ansprechen kann, der viel größer ist als von Unicode benötigt, handelt es sich um die Tatsache, dass ein negativer Wert * einer Rune zugewiesen werden kann. Dies hätte vermieden werden können, wenn es sich um eine vorzeichenlose Ganzzahl handelte. Aber es könnte andere Überlegungen geben, die Sinn machen, dass eine Rune immer noch ein signierter Typ ist, und ich frage mich, was das ist. –

+0

@TapanKarecha: Sicher, aber Sie könnten auch einen positiven Wert außerhalb des Unicode-Bereichs zuweisen. Keines wäre gültiger Unicode. (Negative Zahlen sind möglicherweise offensichtlicher als Fehlerbedingung, wie aus C entnommen?) – Ryan

+0

. @ False: Ja, am positiven Ende des Typbereichs sind ungültige Werte vorhanden, die jedoch ungültige Werte haben Enden der Typenreihe ist etwas, mit dem ich Probleme habe, als ein Konzept zu behandeln. Wie Sie sagten, wenn der Typ nicht signiert wurde, muss ich mich nicht darum kümmern, nach dem negativen Wert zu suchen, was bei der Validierung um eine Prüfung weniger ist. –

8

ich gegoogelt und gefunden: https://groups.google.com/forum/#!topic/golang-nuts/d3_GPK8bwBg

Dieses mehrmals gefragt wurde. Rune belegt 4 Bytes und nicht nur eins, weil es Unicode-Codepunkte und nicht nur ASCII-Zeichen speichern soll. Wie Array-Indizes ist der Datentyp signiert, so dass Sie Überläufe oder andere Fehler bei der Arithmetik mit diesen Typen leicht erkennen können.

+0

Alle Antworten in diesem Thread argumentieren, dass genügend Platz vorhanden ist, um alle Codepunkte von Unicode in einer 32-Bit-Ganzzahl mit Vorzeichen zu referenzieren. Daher verstehe ich, dass Rune groß genug ist, um den Unicode-Bereich zu adressieren. Die Frage nach der Wahl des Typs bleibt offen. Warum nicht uint16 (das einen vergleichbaren Wertebereich für positive Ganzzahlen hat), aber nur den halben Platz als int32 verwendet? –

+1

@TapanKarecha: Uint16 passt jedoch nicht alle Unicode. Es passt ein wirklich großer Teil davon, aber Unicode endet bei '0x10fffd'. – Ryan

+0

Ich sehe deinen Punkt @ False. Ich stimme zu, dass uint16 nicht groß genug ist. Die Frage (auf die Gefahr hin, sich zu wiederholen) über die Wahl von int32 statt von uint32 bleibt bestehen. –