2016-06-09 13 views
3

Ich habe folgendes Beispiel aus dem Buch Golang Addison-Wesley genommen, die ich etwas geändert haben:Warum explodiert Byte-Cast inkonsistent Golan?

package main 

import "fmt" 

// pc[i] is the population count of i. 
var pc [256]byte 

func init() { 
    for i := range pc { 
     pc[i] = pc[i/2] + byte(i&1) 
    } 
} 

// PopCount returns the population count (number of set bits) of x. 
func PopCount(x uint64) int { 
    fmt.Printf("Value is %d\n", x) 
    fmt.Printf("byte(%d>>(0*8)) is %d\n", x, byte(x>>(0*8))) 
    y := byte(x>>(0*8)) 
    return int(pc[y] + 
     pc[byte(x>>(1*8))] + 
     pc[byte(x>>(2*8))] + 
     pc[byte(x>>(3*8))] + 
     pc[byte(x>>(4*8))] + 
     pc[byte(x>>(5*8))] + 
     pc[byte(x>>(6*8))] + 
     pc[byte(x>>(7*8))]) 
} 
func main() { 
    // fmt.Println(byte(256>>(0*8))) // This blows up, but doesn't blow up on line 19 or line 20, why? 
    fmt.Println(PopCount(256)) 
} 

Hier ist der gleiche Code auf dem Spielplatz: bei example-code einfach den Link abläuft, hier ist der Spielplatz wo Sie die oben und das Spiel einfügen können: go playground

Wenn Sie uncomment

// fmt.Println(byte(256>>(0*8))) 

Sie eine Fehlermeldung erhalten:

Da dies in PopCount ohne Sprengung getan wird, verstehe ich nicht, was los ist. Kann mir jemand erklären, warum es explodiert, wenn ich es in main mache, aber nicht in der Funktion PopCount?

Ich glaube, ich vermisse etwas offensichtlich!

Antwort

3

Das liegt daran, dass 256>>(0*8) (entspricht 256), eine nicht typisierte Konstante ist, die zu groß ist in einer byte die Regeln in der language spec Zustand

A constant value x can be converted to type T in any of these cases:

  • x is representable by a value of type T.
  • x is a floating-point constant, T is a floating-point type, and x is representable by a value of type T after rounding using IEEE 754 round-to-even rules, but with an IEEE -0.0 further rounded to an unsigned 0.0. The constant T(x) is the rounded value.
  • x is an integer constant and T is a string type. The same rule as for non-constant x applies in this case.

In Ihrem PopCount Funktion zu passen, der 256 Wert ist vom Typ uint64, der in eine byte konvertiert werden kann, die auf 0 abgeschnitten wird.

+0

Gore> var x uint64 = 256 Gore> Byte (x) 0x0 Als Beispiel in Gore –

+0

@Jake_Howard: nicht sicher, was das bedeutet, oder wenn Sie oder nicht andere Meinung. – JimB

+0

Entschuldigung, ich hätte klarer sein sollen. Gore ist ein Replikat für go, das sind zwei Zeilen Input und Output, die beweisen, was du gesagt hast, gedacht, dass es jemandem helfen könnte, damit zu spielen und sich selbst zu beweisen, dass es funktioniert. –