├── README.md ├── examples ├── array-copy.go ├── arrays-pass.go ├── arrays.go ├── bool-bits.go ├── bool.go ├── byte-declarations.go ├── constants-compression.go ├── constants-iota-expr.go ├── constants-iota-generator-fun │ ├── combined.go │ ├── main.go │ └── state_string.go ├── constants-iota-types-replaced.go ├── constants-iota-types.go ├── constants-iota.go ├── constants-time-2-behind.go ├── constants-time-2.go ├── constants-time-3.go ├── constants-time-4.go ├── constants-time-5.go ├── constants-time-err.txt ├── constants-time.go ├── empty-struct-array.go ├── empty-struct-nested.go ├── empty-struct-slice.go ├── empty-struct-use.go ├── empty-struct.go ├── float-casting.go ├── floats-math-const-expl.go ├── floats-math-const.go ├── floats-math-vars-expl.go ├── floats-math-vars.go ├── floats-sizes.go ├── int-32bit.txt ├── int-arch-faker.go ├── int-casting.go ├── int-example.go ├── int-sizes.txt ├── int.go ├── interfaces-nils.go ├── interfaces.go ├── ints.go ├── maps-rewrite.txt ├── pointer.go ├── position-struct.go ├── runes-slice.go ├── runes-strings.go ├── runes.go ├── slice-header.txt ├── slices-sizes.go ├── slices.go ├── strings-indexing-awry-explained.go ├── strings-indexing-awry-fixed.go ├── strings-indexing-awry.go ├── strings-indexing-bytes.go ├── strings-indexing.go ├── strings-loop-fixed.go ├── strings-loop.go ├── strings-range-null.go ├── strings-range.go ├── strings-sizes.go ├── strings-slice-comparison-2.go ├── strings-slice-comparison-3.go ├── strings-slice-comparison.go ├── strings-slice-comparison.txt ├── strings.go ├── structs-sizes-complex.go ├── structs-sizes-padding-alt.go ├── structs-sizes-padding-bools-more-awry.go ├── structs-sizes-padding-bools-more.go ├── structs-sizes-padding-bools.go ├── structs-sizes-padding-explained.go ├── structs-sizes-padding.go ├── structs-sizes.go ├── structs.go └── uints.go ├── go.mod ├── go.sum ├── helpers └── size │ └── size.go ├── html └── ints.html ├── presentation.slide └── theme ├── static ├── article.css ├── dir.css ├── dir.js ├── favicon.ico ├── jquery-ui.js ├── notes.css ├── notes.js ├── slides.js └── styles.css └── templates ├── action.tmpl ├── article.tmpl ├── dir.tmpl └── slides.tmpl /README.md: -------------------------------------------------------------------------------- 1 | # All Types of Go Types 2 | 3 | ## GoWest 2020 4 | 5 | Carson Anderson 6 | 7 | DevX Engineer, Weave 8 | 9 | @carson_ops 10 | 11 | ## Runing it Locally 12 | 13 | This presentation uses a custom theme and can be run locally by installing the present tool and starting it: 14 | 15 | ```bash 16 | present -use_playground=false -base theme 17 | ``` 18 | -------------------------------------------------------------------------------- /examples/array-copy.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | arr := [3]bool{true, false, true} 7 | arrCopy := arr 8 | 9 | // Now change the copy 10 | arrCopy[1] = true 11 | 12 | fmt.Println("arr", arr) 13 | fmt.Println("arrCopy", arrCopy) 14 | } 15 | -------------------------------------------------------------------------------- /examples/arrays-pass.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | var arr [3]bool 7 | changeToTrue(arr) 8 | fmt.Println(arr) 9 | } 10 | 11 | func changeToTrue(arr [3]bool) { 12 | for i := range arr { 13 | arr[i] = true 14 | } 15 | } 16 | 17 | // END OMIT 18 | -------------------------------------------------------------------------------- /examples/arrays.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "unsafe" 6 | ) 7 | 8 | func main() { 9 | var bools [50]bool 10 | fmt.Println("size is", unsafe.Sizeof(bools), "bytes") 11 | 12 | fmt.Println("index 0 is:", bools[0]) 13 | 14 | bools[42] = true 15 | fmt.Println("index 42 is:", bools[42]) 16 | } 17 | -------------------------------------------------------------------------------- /examples/bool-bits.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "unsafe" 6 | ) 7 | 8 | func main() { 9 | var b bool 10 | fmt.Println(unsafe.Sizeof(b)*8, "bits") 11 | } 12 | 13 | // Partial copy of https://golang.org/src/unsafe/unsafe.go?s=8189:8225#L178 14 | // START OMIT 15 | // Sizeof takes an expression x of any type and returns the size in bytes 16 | // of a hypothetical variable v as if v was declared via var v = x. 17 | // The size does not include any memory possibly referenced by x. 18 | // For instance, if x is a slice, Sizeof returns the size of the slice 19 | // descriptor, not the size of the memory referenced by the slice. 20 | // The return value of Sizeof is a Go constant. 21 | func Sizeof(x ArbitraryType) uintptr { 22 | // END OMIT 23 | return 0 24 | } 25 | 26 | type ArbitraryType string 27 | -------------------------------------------------------------------------------- /examples/bool.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "unsafe" 6 | ) 7 | 8 | func main() { 9 | var b bool 10 | fmt.Println(unsafe.Sizeof(b)) 11 | } 12 | 13 | // Partial copy of https://golang.org/src/unsafe/unsafe.go?s=8189:8225#L178 14 | // START OMIT 15 | // Sizeof takes an expression x of any type and returns the size in bytes // HL 16 | // of a hypothetical variable v as if v was declared via var v = x. 17 | // The size does not include any memory possibly referenced by x. 18 | // For instance, if x is a slice, Sizeof returns the size of the slice 19 | // descriptor, not the size of the memory referenced by the slice. 20 | // The return value of Sizeof is a Go constant. 21 | func Sizeof(x ArbitraryType) uintptr { 22 | // END OMIT 23 | return 0 24 | } 25 | 26 | type ArbitraryType string 27 | -------------------------------------------------------------------------------- /examples/byte-declarations.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | var ( 6 | b1 byte = 0 // integer literal 7 | b2 byte = 0xa // hex notation 8 | b3 byte = 'd' // rune notation 9 | b4 byte = 1_01 // integer literal w/underscore 10 | b5 byte = 0b1100110 // binary notation 11 | ) 12 | 13 | func main() { 14 | // Bytes are an alias to int8, and are printed as one by default 15 | fmt.Println(b1, b2, b3, b4, b5) 16 | } 17 | -------------------------------------------------------------------------------- /examples/constants-compression.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | const ( 6 | Created, Starting, Started, Done = iota, iota, iota, iota 7 | ) 8 | 9 | func main() { 10 | fmt.Println(Created, Starting, Started, Done) 11 | } 12 | -------------------------------------------------------------------------------- /examples/constants-iota-expr.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | // BEGIN OMIT 6 | const ( 7 | x = iota * 2 // index 0 means iota == 0 8 | y = iota + iota // index 1 means iota == 1 9 | _ // index 2 means iota == 2 10 | z = iota * 1.002 // index 3 means iota == 3 11 | ) 12 | 13 | func main() { 14 | fmt.Println(x, y, z) 15 | } 16 | 17 | // END OMIT 18 | -------------------------------------------------------------------------------- /examples/constants-iota-generator-fun/combined.go: -------------------------------------------------------------------------------- 1 | // This file has been MANUALLY CREATED by merging the code from `main.go` 2 | // and the generated code from `state_string.go` together. 3 | // 4 | // This files has been created for easy use in the play command during present 5 | // THIS IS NOT REQUIRED FOR NORMAL USE 6 | 7 | // This file is in it's own folder because that is a requirement for 8 | // go generate to work. 9 | package main 10 | 11 | import ( 12 | "fmt" 13 | "strconv" 14 | ) 15 | 16 | // BEGIN OMIT 17 | //go:generate stringer -type=State // HL 18 | type State int 19 | 20 | const ( 21 | Created State = iota 22 | Starting 23 | Started 24 | Done 25 | ) 26 | 27 | func main() { 28 | fmt.Println(Created, Starting, Started, Done) 29 | } 30 | 31 | // END OMIT 32 | 33 | // Code generated by "stringer -type=State"; DO NOT EDIT. 34 | 35 | func _() { 36 | // An "invalid array index" compiler error signifies that the constant values have changed. 37 | // Re-run the stringer command to generate them again. 38 | var x [1]struct{} 39 | _ = x[Created-0] 40 | _ = x[Starting-1] 41 | _ = x[Started-2] 42 | _ = x[Done-3] 43 | } 44 | 45 | const _State_name = "CreatedStartingStartedDone" 46 | 47 | var _State_index = [...]uint8{0, 7, 15, 22, 26} 48 | 49 | func (i State) String() string { 50 | if i < 0 || i >= State(len(_State_index)-1) { 51 | return "State(" + strconv.FormatInt(int64(i), 10) + ")" 52 | } 53 | return _State_name[_State_index[i]:_State_index[i+1]] 54 | } 55 | -------------------------------------------------------------------------------- /examples/constants-iota-generator-fun/main.go: -------------------------------------------------------------------------------- 1 | // This file is in it's own folder because that is a requirement for 2 | // go generate to work. 3 | package main 4 | 5 | import "fmt" 6 | 7 | // BEGIN OMIT 8 | //go:generate stringer -type=State // HL 9 | type State int 10 | 11 | const ( 12 | Created State = iota 13 | Starting 14 | Started 15 | Done 16 | ) 17 | 18 | func main() { 19 | fmt.Println(Created, Starting, Started, Done) 20 | } 21 | 22 | // END OMIT 23 | -------------------------------------------------------------------------------- /examples/constants-iota-generator-fun/state_string.go: -------------------------------------------------------------------------------- 1 | // Code generated by "stringer -type=State"; DO NOT EDIT. 2 | 3 | package main 4 | 5 | import "strconv" 6 | 7 | func _() { 8 | // An "invalid array index" compiler error signifies that the constant values have changed. 9 | // Re-run the stringer command to generate them again. 10 | var x [1]struct{} 11 | _ = x[Created-0] 12 | _ = x[Starting-1] 13 | _ = x[Started-2] 14 | _ = x[Done-3] 15 | } 16 | 17 | const _State_name = "CreatedStartingStartedDone" 18 | 19 | var _State_index = [...]uint8{0, 7, 15, 22, 26} 20 | 21 | func (i State) String() string { 22 | if i < 0 || i >= State(len(_State_index)-1) { 23 | return "State(" + strconv.FormatInt(int64(i), 10) + ")" 24 | } 25 | return _State_name[_State_index[i]:_State_index[i+1]] 26 | } 27 | -------------------------------------------------------------------------------- /examples/constants-iota-types-replaced.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | // BEGIN OMIT 6 | const ( 7 | a = 0 // iota 8 | b int64 = 1 // iota 9 | c float64 = 2 // iota 10 | d complex128 = 3 // iota 11 | ) 12 | 13 | func main() { 14 | // Print value and type of all constants 15 | fmt.Printf("%[1]v:%[1]T\n", a) 16 | fmt.Printf("%[1]v:%[1]T\n", b) 17 | fmt.Printf("%[1]v:%[1]T\n", c) 18 | fmt.Printf("%[1]v:%[1]T\n", d) 19 | } 20 | 21 | // END OMIT 22 | -------------------------------------------------------------------------------- /examples/constants-iota-types.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | // BEGIN OMIT 6 | const ( 7 | a = iota 8 | b int64 = iota 9 | c float64 = iota 10 | d complex128 = iota 11 | ) 12 | 13 | // END OMIT 14 | 15 | func main() { 16 | // Print value and type of all constants 17 | fmt.Printf("%[1]v:%[1]T\n", a) 18 | fmt.Printf("%[1]v:%[1]T\n", b) 19 | fmt.Printf("%[1]v:%[1]T\n", c) 20 | fmt.Printf("%[1]v:%[1]T\n", d) 21 | } 22 | -------------------------------------------------------------------------------- /examples/constants-iota.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | const ( 6 | Created = iota 7 | Starting 8 | Started 9 | Done 10 | ) 11 | 12 | func main() { 13 | fmt.Println(Created, Starting, Started, Done) 14 | } 15 | -------------------------------------------------------------------------------- /examples/constants-time-2-behind.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func main() { 9 | // BEGIN OMIT 10 | const sleepSeconds = 2 11 | // END OMIT 12 | 13 | fmt.Print("sleeping for ", sleepSeconds, " seconds...") 14 | // invalid code do demonstrate the idea beind untyped constants OMIT 15 | time.Sleep(time.Second * time.Duration(sleepSeconds)) // HL 16 | fmt.Println("done") 17 | } 18 | -------------------------------------------------------------------------------- /examples/constants-time-2.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func main() { 9 | // BEGIN OMIT 10 | const sleepSeconds = 2 11 | // END OMIT 12 | 13 | fmt.Print("sleeping for ", sleepSeconds, " seconds...") 14 | time.Sleep(time.Second * sleepSeconds) 15 | fmt.Println("done") 16 | } 17 | -------------------------------------------------------------------------------- /examples/constants-time-3.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "strconv" 7 | "time" 8 | ) 9 | 10 | func main() { 11 | // BEGIN OMIT 12 | sleepSeconds := 2 13 | // END OMIT 14 | 15 | if len(os.Args) > 1 { 16 | sleepSeconds, _ = strconv.Atoi(os.Args[1]) 17 | } 18 | 19 | fmt.Print("sleeping for ", sleepSeconds, " seconds...") 20 | time.Sleep(time.Second * sleepSeconds) 21 | fmt.Println("done") 22 | } 23 | -------------------------------------------------------------------------------- /examples/constants-time-4.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "strconv" 7 | "time" 8 | ) 9 | 10 | func main() { 11 | sleepSeconds := 2 12 | 13 | if len(os.Args) > 1 { 14 | sleepSeconds, _ = strconv.Atoi(os.Args[1]) 15 | } 16 | 17 | fmt.Print("sleeping for ", sleepSeconds, " seconds...") 18 | time.Sleep(time.Second * time.Duration(sleepSeconds)) // HL 19 | fmt.Println("done") 20 | } 21 | -------------------------------------------------------------------------------- /examples/constants-time-5.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func main() { 9 | const sleepSeconds time.Duration = 2 10 | 11 | fmt.Print("sleeping for ", sleepSeconds, " seconds...") 12 | time.Sleep(time.Second * sleepSeconds) // HL 13 | fmt.Println("done") 14 | } 15 | -------------------------------------------------------------------------------- /examples/constants-time-err.txt: -------------------------------------------------------------------------------- 1 | ./prog.go:19:28: invalid operation: time.Second * sleepSeconds 2 | (mismatched types time.Duration and int) 3 | -------------------------------------------------------------------------------- /examples/constants-time.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func main() { 9 | fmt.Print("sleeping for 2 seconds...") 10 | time.Sleep(time.Second * 2) 11 | fmt.Println("done") 12 | } 13 | -------------------------------------------------------------------------------- /examples/empty-struct-array.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "unsafe" 6 | ) 7 | 8 | func main() { 9 | var structArray [100]struct{} 10 | fmt.Println(unsafe.Sizeof(structArray)) 11 | } 12 | -------------------------------------------------------------------------------- /examples/empty-struct-nested.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "unsafe" 6 | ) 7 | 8 | func main() { 9 | var nestedStruct struct { 10 | a struct{} 11 | b struct{} 12 | } 13 | fmt.Println(unsafe.Sizeof(nestedStruct)) 14 | } 15 | -------------------------------------------------------------------------------- /examples/empty-struct-slice.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "unsafe" 6 | ) 7 | 8 | func main() { 9 | // use make to create a slice of len 100 10 | structSlice := make([]struct{}, 100) 11 | fmt.Println(unsafe.Sizeof(structSlice)) 12 | } 13 | -------------------------------------------------------------------------------- /examples/empty-struct-use.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func main() { 9 | done := make(chan struct{}) 10 | 11 | fmt.Print("Sleeping...") 12 | go func() { 13 | time.Sleep(time.Second) 14 | done <- struct{}{} 15 | }() 16 | 17 | <-done 18 | fmt.Println("done") 19 | } 20 | -------------------------------------------------------------------------------- /examples/empty-struct.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "unsafe" 6 | ) 7 | 8 | func main() { 9 | var empty struct{} 10 | fmt.Println(unsafe.Sizeof(empty)) 11 | } 12 | -------------------------------------------------------------------------------- /examples/float-casting.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | var f32 float32 = 1.002 7 | var f64 float64 = 1.002 8 | 9 | fmt.Println(f64 == float64(f32)) 10 | fmt.Println(f32 == float32(f64)) 11 | } 12 | -------------------------------------------------------------------------------- /examples/floats-math-const-expl.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | const ( 7 | a = 0.1 8 | b = 0.2 9 | c = 0.3 10 | ) 11 | 12 | fmt.Printf("a: %.20f\n", a) 13 | fmt.Printf("b: %.20f\n", b) 14 | fmt.Printf("a+b: %.20f\n", a+b) 15 | fmt.Printf("c: %.20f\n", c) 16 | } 17 | -------------------------------------------------------------------------------- /examples/floats-math-const.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | const ( 7 | a = 0.1 8 | b = 0.2 9 | c = 0.3 10 | ) 11 | fmt.Println(a+b == c) 12 | } 13 | -------------------------------------------------------------------------------- /examples/floats-math-vars-expl.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | var ( 7 | a = 0.1 8 | b = 0.2 9 | c = 0.3 10 | ) 11 | 12 | fmt.Printf("a: %.20f\n", a) 13 | fmt.Printf("b: %.20f\n", b) 14 | fmt.Printf("a+b: %.20f\n", a+b) 15 | fmt.Printf("c: %.20f\n", c) 16 | } 17 | -------------------------------------------------------------------------------- /examples/floats-math-vars.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | var ( 7 | a = 0.1 8 | b = 0.2 9 | c = 0.3 10 | ) 11 | fmt.Println(a+b == c) 12 | } 13 | -------------------------------------------------------------------------------- /examples/floats-sizes.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "unsafe" 6 | ) 7 | 8 | func main() { 9 | var f32 float32 = 1.002 10 | fmt.Println(unsafe.Sizeof(f32)*8, "bits") 11 | 12 | var f64 float64 = 1.002 13 | fmt.Println(unsafe.Sizeof(f64)*8, "bits") 14 | } 15 | -------------------------------------------------------------------------------- /examples/int-32bit.txt: -------------------------------------------------------------------------------- 1 | $ GOARCH=386 go run examples/int.go 2 | 32 bits 3 | 32 bits 4 | -------------------------------------------------------------------------------- /examples/int-arch-faker.go: -------------------------------------------------------------------------------- 1 | // This file fakes the output of 2 | // GOARCH=386 go run examples/int.go 3 | 4 | package main 5 | 6 | import ( 7 | "fmt" 8 | ) 9 | 10 | // BEGIN OMIT 11 | // command: GOARCH=386 go run examples/int.go 12 | // END OMIT 13 | 14 | func main() { 15 | fmt.Println("32 bits") 16 | fmt.Println("32 bits") 17 | } 18 | -------------------------------------------------------------------------------- /examples/int-casting.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | var i32 int32 = 1002 7 | var i64 int64 = 1002 8 | 9 | fmt.Println(i64 == int64(i32)) 10 | fmt.Println(i32 == int32(i64)) 11 | } 12 | -------------------------------------------------------------------------------- /examples/int-example.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | var i int = 10 7 | var i64 int64 = 10 8 | 9 | fmt.Println(i) 10 | fmt.Println(i64) 11 | } 12 | -------------------------------------------------------------------------------- /examples/int-sizes.txt: -------------------------------------------------------------------------------- 1 | uint either 32 or 64 bits // HL 2 | int same size as uint // HL 3 | uintptr an unsigned integer large enough to store the 4 | uninterpreted bits of a pointer value 5 | -------------------------------------------------------------------------------- /examples/int.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "unsafe" 6 | ) 7 | 8 | func main() { 9 | var i int 10 | fmt.Println(unsafe.Sizeof(i)*8, "bits") 11 | 12 | var u uint 13 | fmt.Println(unsafe.Sizeof(u)*8, "bits") 14 | } 15 | -------------------------------------------------------------------------------- /examples/interfaces-nils.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | var x *int 9 | var y interface{} 10 | 11 | fmt.Println("x == nil:", x == nil) 12 | fmt.Println("y == nil:", x == nil) 13 | fmt.Println("x == y: ", x == y) 14 | } 15 | -------------------------------------------------------------------------------- /examples/interfaces.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | "unsafe" 7 | ) 8 | 9 | // BEGIN OMIT 10 | func printSize(msg string, i interface{}) { 11 | fmt.Printf("\nsizes in bytes for %s '%v':\n", msg, i) 12 | fmt.Println("interface: ", unsafe.Sizeof(i)) 13 | fmt.Println("type: ", reflect.TypeOf(i).Size()) 14 | } 15 | 16 | func main() { 17 | printSize("bool", true) 18 | printSize("untyped const", 1) 19 | printSize("int32 cast const", int32(1)) 20 | printSize("int64 cast const", int64(1)) 21 | printSize("string", "xxxx") 22 | } 23 | 24 | // END OMIT 25 | -------------------------------------------------------------------------------- /examples/ints.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "unsafe" 6 | ) 7 | 8 | func main() { 9 | var i8 int8 10 | fmt.Println(unsafe.Sizeof(i8)*8, "bits") 11 | 12 | var i16 int16 13 | fmt.Println(unsafe.Sizeof(i16)*8, "bits") 14 | 15 | var i32 int32 16 | fmt.Println(unsafe.Sizeof(i32)*8, "bits") 17 | 18 | var i64 int64 19 | fmt.Println(unsafe.Sizeof(i64)*8, "bits") 20 | } 21 | -------------------------------------------------------------------------------- /examples/maps-rewrite.txt: -------------------------------------------------------------------------------- 1 | v := m["key"] → runtime.mapaccess1(m, ”key", &v) 2 | v, ok := m["key"] → runtime.mapaccess2(m, ”key”, &v, &ok) 3 | m["key"] = 9001 → runtime.mapinsert(m, ”key", 9001) 4 | delete(m, "key") → runtime.mapdelete(m, “key”) 5 | -------------------------------------------------------------------------------- /examples/pointer.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "unsafe" 6 | ) 7 | 8 | func main() { 9 | var b bool 10 | fmt.Println("bool size:", unsafe.Sizeof(b)) 11 | fmt.Println("bool pointer size:", unsafe.Sizeof(&b)) 12 | 13 | var i64 int64 14 | fmt.Println("int64 size:", unsafe.Sizeof(i64)) 15 | fmt.Println("int64 pointer size:", unsafe.Sizeof(&i64)) 16 | 17 | s := []bool{} 18 | fmt.Println("slice size:", unsafe.Sizeof(s)) 19 | fmt.Println("slice pointer size:", unsafe.Sizeof(&s)) 20 | } 21 | -------------------------------------------------------------------------------- /examples/position-struct.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "unsafe" 6 | ) 7 | 8 | type position struct { 9 | x, y int8 10 | } 11 | 12 | func main() { 13 | fmt.Println("position struct sizes") 14 | 15 | // empty vector struct is two bytes 16 | var p position 17 | fmt.Println("single: ", unsafe.Sizeof(p)) 18 | 19 | // array of positions is len * 2 bytes, or 200 bytes 20 | var positionArray [100]position 21 | fmt.Println("len 100 array: ", unsafe.Sizeof(positionArray)) 22 | 23 | // slize of position slice is always slice header length 24 | // note that the underlying array for this slice still exists 25 | // and still uses 200 bytes for a capacity of 100 26 | positionSlice := make([]position, 100) 27 | fmt.Println("len 100 slice: ", unsafe.Sizeof(positionSlice)) 28 | } 29 | -------------------------------------------------------------------------------- /examples/runes-slice.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | var ( 7 | x = 'x' 8 | y = '😊' 9 | ni = '日' 10 | ) 11 | 12 | fmt.Print( 13 | []byte(string(x)), "\n", 14 | []byte(string(y)), "\n", 15 | []byte(string(ni)), "\n", 16 | ) 17 | } 18 | -------------------------------------------------------------------------------- /examples/runes-strings.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | var ( 7 | x = 'x' 8 | y = '😊' 9 | ni = '日' 10 | ) 11 | 12 | fmt.Println( 13 | string(x), 14 | string(y), 15 | string(ni), 16 | ) 17 | } 18 | -------------------------------------------------------------------------------- /examples/runes.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | var ( 7 | x = 'x' 8 | y = '😊' 9 | ni = '日' 10 | ) 11 | 12 | fmt.Println(x, y, ni) 13 | } 14 | -------------------------------------------------------------------------------- /examples/slice-header.txt: -------------------------------------------------------------------------------- 1 | type sliceHeader struct { 2 | ptr *[]Elem // 8 bytes for amd64 3 | len int // 8 bytes for amd64 4 | cap int // 8 bytes for amd64 5 | } 6 | -------------------------------------------------------------------------------- /examples/slices-sizes.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "unsafe" 6 | ) 7 | 8 | func main() { 9 | s1 := []bool{} 10 | fmt.Println("header bytes: ", unsafe.Sizeof(s1)) 11 | fmt.Println( 12 | "array bytes: ", cap(s1), 13 | ) 14 | 15 | fmt.Println() 16 | 17 | s2 := make([]bool, 100) 18 | fmt.Println("header bytes: ", unsafe.Sizeof(s2)) 19 | fmt.Println( 20 | "array bytes: ", cap(s2), 21 | ) 22 | } 23 | -------------------------------------------------------------------------------- /examples/slices.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | // bools := []bool{true, true, false, false} 7 | // printBools(bools) 8 | 9 | // rangeSlices() 10 | 11 | sliceCopies() 12 | 13 | // stringSliceConversion() 14 | } 15 | 16 | // Go Passes everything by copy. How many values are copied 17 | // when we run this function? 18 | // one value - A slice pointer 19 | // three values - All list elements 20 | // four values - All list elements 21 | func printBools(bools []bool) { 22 | for i, b := range bools { 23 | fmt.Println("index", i, "is", b) 24 | } 25 | } 26 | 27 | // why can you range over a nil slice? 28 | func rangeSlices() { 29 | // Yep! 30 | var bools []bool 31 | for _, b := range bools { 32 | fmt.Println(b) 33 | } 34 | 35 | // And you can append to one too! 36 | // very handy with maps of slices 37 | bools = append(bools, true) 38 | } 39 | 40 | // Do slice copies cause allocations? 41 | func sliceCopies() { 42 | slice := []byte{0x1, 0x2, 0x3} 43 | fmt.Println(slice[0], &slice[0]) 44 | 45 | newSlice := slice 46 | fmt.Println(newSlice[0], &newSlice[0]) 47 | 48 | // modify a member 49 | slice[0] = 0x4 50 | fmt.Println(slice[0], &slice[0]) 51 | fmt.Println(newSlice[0], &newSlice[0]) 52 | } 53 | 54 | // Do slice conversions caus allocations? 55 | // i.e. is new data created when you `s := string(slice)`? 56 | func stringSliceConversion() { 57 | slice := []byte{0x1, 0x2, 0x3} 58 | fmt.Println(&slice[0]) 59 | 60 | str := string(slice) 61 | 62 | newSlice := []byte(str) 63 | fmt.Println(&newSlice[0]) 64 | 65 | // modify a member 66 | slice[0] = 0x4 67 | fmt.Println(slice[0], &slice[0]) 68 | fmt.Println(newSlice[0], &newSlice[0]) 69 | } 70 | -------------------------------------------------------------------------------- /examples/strings-indexing-awry-explained.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | s := "I am a string" 9 | fmt.Println([]byte(s)) 10 | x := s[3] 11 | fmt.Println("at index 3: ", x) 12 | 13 | fmt.Println() 14 | 15 | s = "I ám a string" 16 | fmt.Println([]byte(s)) 17 | x = s[3] 18 | fmt.Println("at index 3: ", x) 19 | } 20 | -------------------------------------------------------------------------------- /examples/strings-indexing-awry-fixed.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | ) 7 | 8 | func main() { 9 | // by explicitly converting to a rune slice 10 | // you can get indexes in a more natural way 11 | // NOTE: This is still not 100% reliable! 12 | s := "I ám a string" 13 | x := []rune(s)[3] // HL 14 | fmt.Println("at index 3: ", x) 15 | fmt.Println("type is: ", reflect.TypeOf(x)) 16 | fmt.Println("as string: ", string(x)) 17 | } 18 | -------------------------------------------------------------------------------- /examples/strings-indexing-awry.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | ) 7 | 8 | func main() { 9 | // strings with non-ascii bytes will mess up indexing 10 | s := "I ám a string" 11 | x := s[3] 12 | fmt.Println("at index 3: ", x) 13 | fmt.Println("type is: ", reflect.TypeOf(x)) 14 | fmt.Println("as string: ", string(x)) 15 | } 16 | -------------------------------------------------------------------------------- /examples/strings-indexing-bytes.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | ) 7 | 8 | func main() { 9 | buf := []byte("I á") 10 | buf = append(buf, 0x00) // write nul byte 11 | buf = append(buf, 'm') // write ascii 'a' byte 12 | s := string(buf) + " a string" 13 | 14 | // prints like normal 15 | fmt.Printf("s is : '%s'\n", s) 16 | 17 | // even a []rune index is still off 18 | x := []rune(s)[3] 19 | fmt.Println("at index 3: ", x) 20 | fmt.Println("type is: ", reflect.TypeOf(x)) 21 | fmt.Println("as string: '", string(x), "'") 22 | } 23 | -------------------------------------------------------------------------------- /examples/strings-indexing.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | ) 7 | 8 | func main() { 9 | // ascii only strings can be safely indexed as normal 10 | s := "I am a string" 11 | x := s[3] 12 | fmt.Println("at index 3: ", x) 13 | fmt.Println("type is: ", reflect.TypeOf(x)) 14 | fmt.Println("as string: ", string(x)) 15 | } 16 | -------------------------------------------------------------------------------- /examples/strings-loop-fixed.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | const s = `西に行く` 7 | 8 | runes := []rune(s) 9 | for i := 0; i < len(runes); i++ { 10 | fmt.Println( 11 | runes[i], ":", string(runes[i]), 12 | ) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /examples/strings-loop.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | const s = `西に行く` 7 | 8 | for i := 0; i < len(s); i++ { 9 | fmt.Println( 10 | s[i], ":", string(s[i]), 11 | ) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /examples/strings-range-null.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | raw := []byte(string(`西に`)) 7 | raw = append(raw, 0b0) // add NULL byte in the middle 8 | raw = append(raw, []byte(string(`行く`))...) 9 | 10 | s := string(raw) 11 | 12 | for _, x := range s { 13 | fmt.Println( 14 | x, ":", string(x), 15 | ) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /examples/strings-range.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | const s = `西に行く` 7 | 8 | for _, x := range s { 9 | fmt.Println( 10 | x, ":", string(x), 11 | ) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /examples/strings-sizes.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "unsafe" 6 | ) 7 | 8 | func main() { 9 | s := "I am a string" 10 | fmt.Println("string size: ", unsafe.Sizeof(s)) 11 | 12 | s = "I am a longer string" 13 | fmt.Println("longer string size: ", unsafe.Sizeof(s)) 14 | } 15 | -------------------------------------------------------------------------------- /examples/strings-slice-comparison-2.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "unsafe" 6 | ) 7 | 8 | func main() { 9 | fmt.Println("string sizes: ") 10 | var str string = "Hi" 11 | fmt.Println("header: ", unsafe.Sizeof(str)) 12 | fmt.Println("len: ", len(str)) 13 | fmt.Println("total: ", int(unsafe.Sizeof(str))+len(str)) 14 | 15 | fmt.Println() 16 | 17 | fmt.Println("byte slice sizes: ") 18 | slice := []byte(str) 19 | fmt.Println("header: ", unsafe.Sizeof(slice)) 20 | fmt.Println("cap: ", cap(slice)) // you have to use cap for slices 21 | fmt.Println("total: ", int(unsafe.Sizeof(slice))+cap(slice)) 22 | } 23 | -------------------------------------------------------------------------------- /examples/strings-slice-comparison-3.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | str := "Hi" 9 | 10 | slice := []byte(str) 11 | 12 | slice[1] = 'm' 13 | slice = append(slice, 109, 109, 109, 240, 159, 164, 148) 14 | 15 | // print proof 16 | fmt.Println(str) 17 | fmt.Println(string(slice)) 18 | } 19 | -------------------------------------------------------------------------------- /examples/strings-slice-comparison.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "unsafe" 6 | ) 7 | 8 | func main() { 9 | var str string = "Hi" 10 | fmt.Println("string bytes: ", unsafe.Sizeof(str)) 11 | 12 | slice := []byte(str) 13 | fmt.Println("slice bytes: ", unsafe.Sizeof(slice)) 14 | } 15 | -------------------------------------------------------------------------------- /examples/strings-slice-comparison.txt: -------------------------------------------------------------------------------- 1 | type stringHeader struct { 2 | ptr *[]Elem // 8 bytes for amd64 3 | len int // 8 bytes for amd64 4 | } 5 | 6 | type sliceHeader struct { 7 | ptr *[]Elem // 8 bytes for amd64 8 | len int // 8 bytes for amd64 9 | cap int // 8 bytes for amd64 10 | } 11 | -------------------------------------------------------------------------------- /examples/strings.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | const goWestEN = `GoWest` 6 | const goWestJP = `西に行く` 7 | 8 | func main() { 9 | fmt.Println("-- ASCII --") 10 | examineString(goWestEN) 11 | 12 | fmt.Println("-- Non-ASCII --") 13 | examineString(goWestJP) 14 | } 15 | 16 | func examineString(s string) { 17 | fmt.Println("Whole string: ", s) 18 | 19 | fmt.Println("Index 0: ", s[0]) 20 | 21 | fmt.Println("for loop:") 22 | for i := 0; i < len(s); i++ { 23 | b := s[i] 24 | // the default Println behavor is to print the type (byte) 25 | fmt.Println("rune: ", b) 26 | 27 | // we have to cast to string to get our character 28 | fmt.Printf("quote: %s\n", string(b)) 29 | } 30 | 31 | fmt.Println("for range loop:") 32 | for _, r := range s { 33 | // the default Println behavor is to print the type (byte slice) 34 | fmt.Println("rune: ", r) 35 | 36 | // we have to cast to string to get our character 37 | fmt.Printf("quote: %s\n", string(r)) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /examples/structs-sizes-complex.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "unsafe" 6 | ) 7 | 8 | func main() { 9 | var data struct { 10 | child struct { 11 | a uint64 // 8 bytes 12 | b uint64 // 8 bytes 13 | } 14 | x uint64 // 8 bytes 15 | y uint64 // 8 bytes 16 | } 17 | 18 | fmt.Println( 19 | unsafe.Sizeof(data.child.a), 20 | "+", 21 | unsafe.Sizeof(data.child.b), 22 | "+", 23 | unsafe.Sizeof(data.x), 24 | "+", 25 | unsafe.Sizeof(data.y), 26 | "=", 27 | unsafe.Sizeof(data), 28 | ) 29 | } 30 | -------------------------------------------------------------------------------- /examples/structs-sizes-padding-alt.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "unsafe" 6 | ) 7 | 8 | func main() { 9 | var data struct { 10 | x uint32 // 4 bytes 11 | y uint32 // 4 bytes 12 | } 13 | fmt.Println( 14 | unsafe.Sizeof(data.x), 15 | "+", 16 | unsafe.Sizeof(data.y), 17 | "=", 18 | unsafe.Sizeof(data), 19 | ) 20 | } 21 | -------------------------------------------------------------------------------- /examples/structs-sizes-padding-bools-more-awry.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "unsafe" 6 | ) 7 | 8 | func main() { 9 | var data struct { 10 | x1 bool // 1 bytes 11 | // [7]byte 12 | y uint64 // 8 bytes 13 | x2 bool // 1 bytes 14 | // [7]byte 15 | } 16 | fmt.Println( 17 | unsafe.Sizeof(data.x1), 18 | "+", 19 | unsafe.Sizeof(data.x2), 20 | "+", 21 | unsafe.Sizeof(data.y), 22 | "=", 23 | unsafe.Sizeof(data), 24 | ) 25 | } 26 | -------------------------------------------------------------------------------- /examples/structs-sizes-padding-bools-more.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "unsafe" 6 | ) 7 | 8 | func main() { 9 | var data struct { 10 | x1 bool // 1 bytes 11 | x2 bool // 1 bytes 12 | // [6]byte 13 | y uint64 // 8 bytes 14 | } 15 | fmt.Println( 16 | unsafe.Sizeof(data.x1), 17 | "+", 18 | unsafe.Sizeof(data.x2), 19 | "+", 20 | unsafe.Sizeof(data.y), 21 | "=", 22 | unsafe.Sizeof(data), 23 | ) 24 | } 25 | -------------------------------------------------------------------------------- /examples/structs-sizes-padding-bools.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "unsafe" 6 | ) 7 | 8 | func main() { 9 | var data struct { 10 | x bool // 1 bytes 11 | // [7]byte 12 | y uint64 // 8 bytes 13 | } 14 | fmt.Println( 15 | unsafe.Sizeof(data.x), 16 | "+", 17 | unsafe.Sizeof(data.y), 18 | "=", 19 | unsafe.Sizeof(data), 20 | ) 21 | } 22 | -------------------------------------------------------------------------------- /examples/structs-sizes-padding-explained.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func main() { 4 | var data struct { 5 | x uint32 // 4 bytes 6 | _ [4]byte 7 | y uint64 // 8 bytes 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /examples/structs-sizes-padding.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "unsafe" 6 | ) 7 | 8 | func main() { 9 | var data struct { 10 | x uint32 // 4 bytes // HL 11 | y uint64 // 8 bytes 12 | } 13 | fmt.Println( 14 | unsafe.Sizeof(data.x), 15 | "+", 16 | unsafe.Sizeof(data.y), 17 | "=", 18 | unsafe.Sizeof(data), 19 | ) 20 | } 21 | -------------------------------------------------------------------------------- /examples/structs-sizes.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "unsafe" 6 | ) 7 | 8 | func main() { 9 | var data struct { 10 | x uint64 // 8 bytes 11 | y uint64 // 8 bytes 12 | } 13 | 14 | fmt.Println( 15 | unsafe.Sizeof(data.x), 16 | "+", 17 | unsafe.Sizeof(data.y), 18 | "=", 19 | unsafe.Sizeof(data), 20 | ) 21 | } 22 | -------------------------------------------------------------------------------- /examples/structs.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | // BEGIN OMIT 6 | type nothin struct{} 7 | 8 | type data struct { 9 | x int 10 | y int64 11 | } 12 | 13 | func main() { 14 | fmt.Println(nothin{}) 15 | fmt.Println(data{1, 2}) 16 | } 17 | 18 | // END OMIT 19 | -------------------------------------------------------------------------------- /examples/uints.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "unsafe" 6 | ) 7 | 8 | func main() { 9 | var ui8 uint8 10 | fmt.Println(unsafe.Sizeof(ui8)*8, "bits") 11 | 12 | var ui16 uint16 13 | fmt.Println(unsafe.Sizeof(ui16)*8, "bits") 14 | 15 | var ui32 uint32 16 | fmt.Println(unsafe.Sizeof(ui32)*8, "bits") 17 | 18 | var ui64 uint64 19 | fmt.Println(unsafe.Sizeof(ui64)*8, "bits") 20 | } 21 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/carsonoid/gowest2020-go-types 2 | 3 | go 1.14 4 | 5 | require ( 6 | github.com/davelaursen/present-plus v0.0.0-20150924164712-83b3dc77501f // indirect 7 | github.com/yuin/goldmark v1.4.0 // indirect 8 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 // indirect 9 | golang.org/x/net v0.0.0-20210614182718-04defd469f4e // indirect 10 | golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect 11 | golang.org/x/tools v0.1.5 // indirect 12 | ) 13 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/davelaursen/present-plus v0.0.0-20150924164712-83b3dc77501f h1:k8Vxh3NlskkR25ewGbCS/ydL18BxYlVFQtfbLuMHx0I= 2 | github.com/davelaursen/present-plus v0.0.0-20150924164712-83b3dc77501f/go.mod h1:fhPWdeZWNxQXWh1odOF0/qlR5B3BdIxQ4OmIv67M838= 3 | github.com/yuin/goldmark v1.1.32 h1:5tjfNdR2ki3yYQ842+eX2sQHeiwpKJ0RnHO4IYOc4V8= 4 | github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 5 | github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 6 | github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= 7 | github.com/yuin/goldmark v1.4.0 h1:OtISOGfH6sOWa1/qXqqAiOIAO6Z5J3AEAE18WAq6BiQ= 8 | github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= 9 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 10 | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 11 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 12 | golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= 13 | golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 14 | golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= 15 | golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 16 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 17 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 18 | golang.org/x/net v0.0.0-20200625001655-4c5254603344 h1:vGXIOMxbNfDTk/aXCmfdLgkrSV+Z2tcbze+pEc3v5W4= 19 | golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= 20 | golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc h1:zK/HqS5bZxDptfPJNq8v7vJfXtkU7r9TLIoSr1bXaP4= 21 | golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= 22 | golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= 23 | golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= 24 | golang.org/x/net v0.0.0-20210614182718-04defd469f4e h1:XpT3nA5TvE525Ne3hInMh6+GETgn27Zfm9dxsThnX2Q= 25 | golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 26 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 27 | golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 28 | golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= 29 | golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 30 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 31 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 32 | golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 33 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 34 | golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 35 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 36 | golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 37 | golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I= 38 | golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 39 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 40 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 41 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 42 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 43 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 44 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 45 | golang.org/x/tools v0.0.0-20200815165600-90abf76919f3 h1:0aScV/0rLmANzEYIhjCOi2pTvDyhZNduBUMD2q3iqs4= 46 | golang.org/x/tools v0.0.0-20200815165600-90abf76919f3/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= 47 | golang.org/x/tools v0.0.0-20200904185747-39188db58858 h1:xLt+iB5ksWcZVxqc+g9K41ZHy+6MKWfXCDsjSThnsPA= 48 | golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= 49 | golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= 50 | golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= 51 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 52 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 53 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= 54 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 55 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= 56 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 57 | -------------------------------------------------------------------------------- /helpers/size/size.go: -------------------------------------------------------------------------------- 1 | package size 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | ) 7 | 8 | func InBits(i interface{}) { 9 | // use reflect to get size in bytes 10 | s := reflect.TypeOf(i).Size() 11 | 12 | // print bytes * 8 to get bits 13 | fmt.Println(s * 8) 14 | } 15 | -------------------------------------------------------------------------------- /html/ints.html: -------------------------------------------------------------------------------- 1 |
Types | 4 |Size | 5 |# Occurences | 6 |
---|---|---|
int | 9 |? bits | 10 |52,626 | 11 |
int8 | 14 |8 bits | 15 |2,578 | 16 |
int16 | 19 |16 bits | 20 |1,855 | 21 |
int32 | 24 |32 bits | 25 |10,899 | 26 |
int64 | 29 |64 bits | 30 |15,419 | 31 |
' + notes[i] + '
'; 101 | } 102 | } 103 | return formattedNotes; 104 | } 105 | 106 | function updateNotes() { 107 | // When triggered from parent window, notesWindow is null 108 | // The storage event listener on notesWindow will update notes 109 | if (!notesWindow) return; 110 | var destSlide = parseInt(localStorage.getItem(destSlideKey()), 10); 111 | var section = sections[destSlide - 1]; 112 | var el = notesWindow.document.getElementById('presenter-notes'); 113 | 114 | if (!el) return; 115 | 116 | if (section && section.Notes) { 117 | el.innerHTML = formatNotes(section.Notes); 118 | } else if (destSlide == 0) { 119 | el.innerHTML = formatNotes(titleNotes); 120 | } else { 121 | el.innerHTML = ''; 122 | } 123 | } 124 | 125 | /* Playground syncing */ 126 | 127 | // When presenter notes are enabled, playground click handlers are 128 | // stored here to sync click events on the correct playground 129 | var playgroundHandlers = { onRun: [], onKill: [], onClose: [] }; 130 | 131 | function updatePlay(e) { 132 | var i = localStorage.getItem('play-index'); 133 | 134 | switch (e.key) { 135 | case 'play-index': 136 | return; 137 | case 'play-action': 138 | // Sync 'run', 'kill', 'close' actions 139 | var action = localStorage.getItem('play-action'); 140 | playgroundHandlers[action][i](e); 141 | return; 142 | case 'play-code': 143 | // Sync code editing 144 | var play = document.querySelectorAll('div.playground')[i]; 145 | play.innerHTML = localStorage.getItem('play-code'); 146 | return; 147 | case 'output-style': 148 | // Sync resizing of playground output 149 | var out = document.querySelectorAll('.output')[i]; 150 | out.style = localStorage.getItem('output-style'); 151 | return; 152 | } 153 | } 154 | 155 | // Reset 'run', 'kill', 'close' storage items when synced 156 | // so that successive actions can be synced correctly 157 | function updatePlayStorage(action, index, e) { 158 | localStorage.setItem('play-index', index); 159 | 160 | if (localStorage.getItem('play-action') === action) { 161 | // We're the receiving window, and the message has been received 162 | localStorage.removeItem('play-action'); 163 | } else { 164 | // We're the triggering window, send the message 165 | localStorage.setItem('play-action', action); 166 | } 167 | 168 | if (action === 'onRun') { 169 | if (localStorage.getItem('play-shiftKey') === 'true') { 170 | localStorage.removeItem('play-shiftKey'); 171 | } else if (e.shiftKey) { 172 | localStorage.setItem('play-shiftKey', e.shiftKey); 173 | } 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /theme/static/slides.js: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | var PERMANENT_URL_PREFIX = '/static/'; 6 | 7 | var SLIDE_CLASSES = ['far-past', 'past', 'current', 'next', 'far-next']; 8 | 9 | var PM_TOUCH_SENSITIVITY = 15; 10 | 11 | var curSlide; 12 | 13 | /* ---------------------------------------------------------------------- */ 14 | /* classList polyfill by Eli Grey 15 | * (http://purl.eligrey.com/github/classList.js/blob/master/classList.js) */ 16 | 17 | if ( 18 | typeof document !== 'undefined' && 19 | !('classList' in document.createElement('a')) 20 | ) { 21 | (function (view) { 22 | var classListProp = 'classList', 23 | protoProp = 'prototype', 24 | elemCtrProto = (view.HTMLElement || view.Element)[protoProp], 25 | objCtr = Object; 26 | (strTrim = 27 | String[protoProp].trim || 28 | function () { 29 | return this.replace(/^\s+|\s+$/g, ''); 30 | }), 31 | (arrIndexOf = 32 | Array[protoProp].indexOf || 33 | function (item) { 34 | for (var i = 0, len = this.length; i < len; i++) { 35 | if (i in this && this[i] === item) { 36 | return i; 37 | } 38 | } 39 | return -1; 40 | }), 41 | // Vendors: please allow content code to instantiate DOMExceptions 42 | (DOMEx = function (type, message) { 43 | this.name = type; 44 | this.code = DOMException[type]; 45 | this.message = message; 46 | }), 47 | (checkTokenAndGetIndex = function (classList, token) { 48 | if (token === '') { 49 | throw new DOMEx( 50 | 'SYNTAX_ERR', 51 | 'An invalid or illegal string was specified' 52 | ); 53 | } 54 | if (/\s/.test(token)) { 55 | throw new DOMEx( 56 | 'INVALID_CHARACTER_ERR', 57 | 'String contains an invalid character' 58 | ); 59 | } 60 | return arrIndexOf.call(classList, token); 61 | }), 62 | (ClassList = function (elem) { 63 | var trimmedClasses = strTrim.call(elem.className), 64 | classes = trimmedClasses ? trimmedClasses.split(/\s+/) : []; 65 | for (var i = 0, len = classes.length; i < len; i++) { 66 | this.push(classes[i]); 67 | } 68 | this._updateClassName = function () { 69 | elem.className = this.toString(); 70 | }; 71 | }), 72 | (classListProto = ClassList[protoProp] = []), 73 | (classListGetter = function () { 74 | return new ClassList(this); 75 | }); 76 | // Most DOMException implementations don't allow calling DOMException's toString() 77 | // on non-DOMExceptions. Error's toString() is sufficient here. 78 | DOMEx[protoProp] = Error[protoProp]; 79 | classListProto.item = function (i) { 80 | return this[i] || null; 81 | }; 82 | classListProto.contains = function (token) { 83 | token += ''; 84 | return checkTokenAndGetIndex(this, token) !== -1; 85 | }; 86 | classListProto.add = function (token) { 87 | token += ''; 88 | if (checkTokenAndGetIndex(this, token) === -1) { 89 | this.push(token); 90 | this._updateClassName(); 91 | } 92 | }; 93 | classListProto.remove = function (token) { 94 | token += ''; 95 | var index = checkTokenAndGetIndex(this, token); 96 | if (index !== -1) { 97 | this.splice(index, 1); 98 | this._updateClassName(); 99 | } 100 | }; 101 | classListProto.toggle = function (token) { 102 | token += ''; 103 | if (checkTokenAndGetIndex(this, token) === -1) { 104 | this.add(token); 105 | } else { 106 | this.remove(token); 107 | } 108 | }; 109 | classListProto.toString = function () { 110 | return this.join(' '); 111 | }; 112 | 113 | if (objCtr.defineProperty) { 114 | var classListPropDesc = { 115 | get: classListGetter, 116 | enumerable: true, 117 | configurable: true, 118 | }; 119 | try { 120 | objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc); 121 | } catch (ex) { 122 | // IE 8 doesn't support enumerable:true 123 | if (ex.number === -0x7ff5ec54) { 124 | classListPropDesc.enumerable = false; 125 | objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc); 126 | } 127 | } 128 | } else if (objCtr[protoProp].__defineGetter__) { 129 | elemCtrProto.__defineGetter__(classListProp, classListGetter); 130 | } 131 | })(self); 132 | } 133 | /* ---------------------------------------------------------------------- */ 134 | 135 | /* Slide movement */ 136 | 137 | function hideHelpText() { 138 | document.getElementById('help').style.display = 'none'; 139 | } 140 | 141 | function getSlideEl(no) { 142 | if (no < 0 || no >= slideEls.length) { 143 | return null; 144 | } else { 145 | return slideEls[no]; 146 | } 147 | } 148 | 149 | function updateSlideClass(slideNo, className) { 150 | var el = getSlideEl(slideNo); 151 | 152 | if (!el) { 153 | return; 154 | } 155 | 156 | if (className) { 157 | el.classList.add(className); 158 | } 159 | 160 | for (var i in SLIDE_CLASSES) { 161 | if (className != SLIDE_CLASSES[i]) { 162 | el.classList.remove(SLIDE_CLASSES[i]); 163 | } 164 | } 165 | } 166 | 167 | function updateSlides() { 168 | if (window.trackPageview) window.trackPageview(); 169 | 170 | for (var i = 0; i < slideEls.length; i++) { 171 | switch (i) { 172 | case curSlide - 2: 173 | updateSlideClass(i, 'far-past'); 174 | break; 175 | case curSlide - 1: 176 | updateSlideClass(i, 'past'); 177 | break; 178 | case curSlide: 179 | updateSlideClass(i, 'current'); 180 | break; 181 | case curSlide + 1: 182 | updateSlideClass(i, 'next'); 183 | break; 184 | case curSlide + 2: 185 | updateSlideClass(i, 'far-next'); 186 | break; 187 | default: 188 | updateSlideClass(i); 189 | break; 190 | } 191 | } 192 | 193 | triggerLeaveEvent(curSlide - 1); 194 | triggerEnterEvent(curSlide); 195 | 196 | window.setTimeout(function () { 197 | // Hide after the slide 198 | disableSlideFrames(curSlide - 2); 199 | }, 301); 200 | 201 | enableSlideFrames(curSlide - 1); 202 | enableSlideFrames(curSlide + 2); 203 | 204 | updateHash(); 205 | } 206 | 207 | function prevSlide() { 208 | hideHelpText(); 209 | if (curSlide > 0) { 210 | curSlide--; 211 | 212 | updateSlides(); 213 | } 214 | 215 | if (notesEnabled) localStorage.setItem(destSlideKey(), curSlide); 216 | } 217 | 218 | function nextSlide() { 219 | hideHelpText(); 220 | if (curSlide < slideEls.length - 1) { 221 | curSlide++; 222 | 223 | updateSlides(); 224 | } 225 | 226 | if (notesEnabled) localStorage.setItem(destSlideKey(), curSlide); 227 | } 228 | 229 | /* Slide events */ 230 | 231 | function triggerEnterEvent(no) { 232 | var el = getSlideEl(no); 233 | if (!el) { 234 | return; 235 | } 236 | 237 | var onEnter = el.getAttribute('onslideenter'); 238 | if (onEnter) { 239 | new Function(onEnter).call(el); 240 | } 241 | 242 | var evt = document.createEvent('Event'); 243 | evt.initEvent('slideenter', true, true); 244 | evt.slideNumber = no + 1; // Make it readable 245 | 246 | el.dispatchEvent(evt); 247 | } 248 | 249 | function triggerLeaveEvent(no) { 250 | var el = getSlideEl(no); 251 | if (!el) { 252 | return; 253 | } 254 | 255 | var onLeave = el.getAttribute('onslideleave'); 256 | if (onLeave) { 257 | new Function(onLeave).call(el); 258 | } 259 | 260 | var evt = document.createEvent('Event'); 261 | evt.initEvent('slideleave', true, true); 262 | evt.slideNumber = no + 1; // Make it readable 263 | 264 | el.dispatchEvent(evt); 265 | } 266 | 267 | /* Touch events */ 268 | 269 | function handleTouchStart(event) { 270 | if (event.touches.length == 1) { 271 | touchDX = 0; 272 | touchDY = 0; 273 | 274 | touchStartX = event.touches[0].pageX; 275 | touchStartY = event.touches[0].pageY; 276 | 277 | document.body.addEventListener('touchmove', handleTouchMove, true); 278 | document.body.addEventListener('touchend', handleTouchEnd, true); 279 | } 280 | } 281 | 282 | function handleTouchMove(event) { 283 | if (event.touches.length > 1) { 284 | cancelTouch(); 285 | } else { 286 | touchDX = event.touches[0].pageX - touchStartX; 287 | touchDY = event.touches[0].pageY - touchStartY; 288 | event.preventDefault(); 289 | } 290 | } 291 | 292 | function handleTouchEnd(event) { 293 | var dx = Math.abs(touchDX); 294 | var dy = Math.abs(touchDY); 295 | 296 | if (dx > PM_TOUCH_SENSITIVITY && dy < (dx * 2) / 3) { 297 | if (touchDX > 0) { 298 | prevSlide(); 299 | } else { 300 | nextSlide(); 301 | } 302 | } 303 | 304 | cancelTouch(); 305 | } 306 | 307 | function cancelTouch() { 308 | document.body.removeEventListener('touchmove', handleTouchMove, true); 309 | document.body.removeEventListener('touchend', handleTouchEnd, true); 310 | } 311 | 312 | /* Preloading frames */ 313 | 314 | function disableSlideFrames(no) { 315 | var el = getSlideEl(no); 316 | if (!el) { 317 | return; 318 | } 319 | 320 | var frames = el.getElementsByTagName('iframe'); 321 | for (var i = 0, frame; (frame = frames[i]); i++) { 322 | disableFrame(frame); 323 | } 324 | } 325 | 326 | function enableSlideFrames(no) { 327 | var el = getSlideEl(no); 328 | if (!el) { 329 | return; 330 | } 331 | 332 | var frames = el.getElementsByTagName('iframe'); 333 | for (var i = 0, frame; (frame = frames[i]); i++) { 334 | enableFrame(frame); 335 | } 336 | } 337 | 338 | function disableFrame(frame) { 339 | frame.src = 'about:blank'; 340 | } 341 | 342 | function enableFrame(frame) { 343 | var src = frame._src; 344 | 345 | if (frame.src != src && src != 'about:blank') { 346 | frame.src = src; 347 | } 348 | } 349 | 350 | function setupFrames() { 351 | var frames = document.querySelectorAll('iframe'); 352 | for (var i = 0, frame; (frame = frames[i]); i++) { 353 | frame._src = frame.src; 354 | disableFrame(frame); 355 | } 356 | 357 | enableSlideFrames(curSlide); 358 | enableSlideFrames(curSlide + 1); 359 | enableSlideFrames(curSlide + 2); 360 | } 361 | 362 | function setupInteraction() { 363 | /* Clicking and tapping */ 364 | 365 | var el = document.createElement('div'); 366 | el.className = 'slide-area'; 367 | el.id = 'prev-slide-area'; 368 | el.addEventListener('click', prevSlide, false); 369 | document.querySelector('section.slides').appendChild(el); 370 | 371 | var el = document.createElement('div'); 372 | el.className = 'slide-area'; 373 | el.id = 'next-slide-area'; 374 | el.addEventListener('click', nextSlide, false); 375 | document.querySelector('section.slides').appendChild(el); 376 | 377 | /* Swiping */ 378 | 379 | document.body.addEventListener('touchstart', handleTouchStart, false); 380 | } 381 | 382 | /* Hash functions */ 383 | 384 | function getCurSlideFromHash() { 385 | var slideNo = parseInt(location.hash.substr(1)); 386 | 387 | if (slideNo) { 388 | curSlide = slideNo - 1; 389 | } else { 390 | curSlide = 0; 391 | } 392 | } 393 | 394 | function updateHash() { 395 | location.replace('#' + (curSlide + 1)); 396 | } 397 | 398 | /* Event listeners */ 399 | 400 | function handleBodyKeyDown(event) { 401 | // If we're in a code element, only handle pgup/down. 402 | var inCode = event.target.classList.contains('code'); 403 | 404 | switch (event.keyCode) { 405 | case 78: // 'N' opens presenter notes window 406 | if (!inCode && notesEnabled) toggleNotesWindow(); 407 | break; 408 | case 72: // 'H' hides the help text 409 | case 27: // escape key 410 | if (!inCode) hideHelpText(); 411 | break; 412 | 413 | case 39: // right arrow 414 | case 13: // Enter 415 | case 32: // space 416 | if (inCode) break; 417 | case 34: // PgDn 418 | nextSlide(); 419 | event.preventDefault(); 420 | break; 421 | 422 | case 37: // left arrow 423 | case 8: // Backspace 424 | if (inCode) break; 425 | case 33: // PgUp 426 | prevSlide(); 427 | event.preventDefault(); 428 | break; 429 | 430 | case 40: // down arrow 431 | if (inCode) break; 432 | nextSlide(); 433 | event.preventDefault(); 434 | break; 435 | 436 | case 38: // up arrow 437 | if (inCode) break; 438 | prevSlide(); 439 | event.preventDefault(); 440 | break; 441 | } 442 | } 443 | 444 | function scaleSmallViewports() { 445 | var el = document.querySelector('section.slides'); 446 | var transform = ''; 447 | var sWidthPx = 1250; 448 | var sHeightPx = 750; 449 | var sAspectRatio = sWidthPx / sHeightPx; 450 | var wAspectRatio = window.innerWidth / window.innerHeight; 451 | 452 | if (wAspectRatio <= sAspectRatio && window.innerWidth < sWidthPx) { 453 | transform = 'scale(' + window.innerWidth / sWidthPx + ')'; 454 | } else if (window.innerHeight < sHeightPx) { 455 | transform = 'scale(' + window.innerHeight / sHeightPx + ')'; 456 | } 457 | el.style.transform = transform; 458 | } 459 | 460 | function addEventListeners() { 461 | document.addEventListener('keydown', handleBodyKeyDown, false); 462 | var resizeTimeout; 463 | window.addEventListener('resize', function () { 464 | // throttle resize events 465 | window.clearTimeout(resizeTimeout); 466 | resizeTimeout = window.setTimeout(function () { 467 | resizeTimeout = null; 468 | scaleSmallViewports(); 469 | }, 50); 470 | }); 471 | 472 | // Force reset transform property of section.slides when printing page. 473 | // Use both onbeforeprint and matchMedia for compatibility with different browsers. 474 | var beforePrint = function () { 475 | var el = document.querySelector('section.slides'); 476 | el.style.transform = ''; 477 | }; 478 | window.onbeforeprint = beforePrint; 479 | if (window.matchMedia) { 480 | var mediaQueryList = window.matchMedia('print'); 481 | mediaQueryList.addListener(function (mql) { 482 | if (mql.matches) beforePrint(); 483 | }); 484 | } 485 | } 486 | 487 | /* Initialization */ 488 | 489 | function addFontStyle() { 490 | var el = document.createElement('link'); 491 | el.rel = 'stylesheet'; 492 | el.type = 'text/css'; 493 | el.href = 494 | '//fonts.googleapis.com/css?family=' + 495 | 'Open+Sans:regular,semibold,italic,italicsemibold|Droid+Sans+Mono'; 496 | 497 | document.body.appendChild(el); 498 | } 499 | 500 | function addGeneralStyle() { 501 | var el = document.createElement('link'); 502 | el.rel = 'stylesheet'; 503 | el.type = 'text/css'; 504 | el.href = PERMANENT_URL_PREFIX + 'styles.css'; 505 | document.body.appendChild(el); 506 | 507 | var el = document.createElement('meta'); 508 | el.name = 'viewport'; 509 | el.content = 'width=device-width,height=device-height,initial-scale=1'; 510 | document.querySelector('head').appendChild(el); 511 | 512 | var el = document.createElement('meta'); 513 | el.name = 'apple-mobile-web-app-capable'; 514 | el.content = 'yes'; 515 | document.querySelector('head').appendChild(el); 516 | 517 | scaleSmallViewports(); 518 | } 519 | 520 | function handleDomLoaded() { 521 | slideEls = document.querySelectorAll('section.slides > article'); 522 | 523 | setupFrames(); 524 | 525 | addFontStyle(); 526 | addGeneralStyle(); 527 | addEventListeners(); 528 | 529 | updateSlides(); 530 | 531 | setupInteraction(); 532 | 533 | if ( 534 | window.location.hostname == 'localhost' || 535 | window.location.hostname == '127.0.0.1' || 536 | window.location.hostname == '::1' 537 | ) { 538 | hideHelpText(); 539 | } 540 | 541 | document.body.classList.add('loaded'); 542 | 543 | setupNotesSync(); 544 | } 545 | 546 | function initialize() { 547 | getCurSlideFromHash(); 548 | 549 | if (window['_DEBUG']) { 550 | PERMANENT_URL_PREFIX = '../'; 551 | } 552 | 553 | if (window['_DCL']) { 554 | handleDomLoaded(); 555 | } else { 556 | document.addEventListener('DOMContentLoaded', handleDomLoaded, false); 557 | } 558 | } 559 | 560 | // If ?debug exists then load the script relative instead of absolute 561 | if (!window['_DEBUG'] && document.location.href.indexOf('?debug') !== -1) { 562 | document.addEventListener( 563 | 'DOMContentLoaded', 564 | function () { 565 | // Avoid missing the DomContentLoaded event 566 | window['_DCL'] = true; 567 | }, 568 | false 569 | ); 570 | 571 | window['_DEBUG'] = true; 572 | var script = document.createElement('script'); 573 | script.type = 'text/javascript'; 574 | script.src = '../slides.js'; 575 | var s = document.getElementsByTagName('script')[0]; 576 | s.parentNode.insertBefore(script, s); 577 | 578 | // Remove this script 579 | s.parentNode.removeChild(s); 580 | } else { 581 | initialize(); 582 | } 583 | 584 | /* Synchronize windows when notes are enabled */ 585 | 586 | function setupNotesSync() { 587 | if (!notesEnabled) return; 588 | 589 | function setupPlayResizeSync() { 590 | var out = document.getElementsByClassName('output'); 591 | for (var i = 0; i < out.length; i++) { 592 | $(out[i]).bind('resize', function (event) { 593 | if ($(event.target).hasClass('ui-resizable')) { 594 | localStorage.setItem('play-index', i); 595 | localStorage.setItem('output-style', out[i].style.cssText); 596 | } 597 | }); 598 | } 599 | } 600 | function setupPlayCodeSync() { 601 | var play = document.querySelectorAll('div.playground'); 602 | for (var i = 0; i < play.length; i++) { 603 | play[i].addEventListener('input', inputHandler, false); 604 | 605 | function inputHandler(e) { 606 | localStorage.setItem('play-index', i); 607 | localStorage.setItem('play-code', e.target.innerHTML); 608 | } 609 | } 610 | } 611 | 612 | setupPlayCodeSync(); 613 | setupPlayResizeSync(); 614 | localStorage.setItem(destSlideKey(), curSlide); 615 | window.addEventListener('storage', updateOtherWindow, false); 616 | } 617 | 618 | // An update to local storage is caught only by the other window 619 | // The triggering window does not handle any sync actions 620 | function updateOtherWindow(e) { 621 | // Ignore remove storage events which are not meant to update the other window 622 | var isRemoveStorageEvent = !e.newValue; 623 | if (isRemoveStorageEvent) return; 624 | 625 | var destSlide = localStorage.getItem(destSlideKey()); 626 | while (destSlide > curSlide) { 627 | nextSlide(); 628 | } 629 | while (destSlide < curSlide) { 630 | prevSlide(); 631 | } 632 | 633 | updatePlay(e); 634 | updateNotes(); 635 | } 636 | -------------------------------------------------------------------------------- /theme/static/styles.css: -------------------------------------------------------------------------------- 1 | @media screen { 2 | /* Framework */ 3 | html { 4 | height: 100%; 5 | } 6 | 7 | body { 8 | margin: 0; 9 | padding: 0; 10 | 11 | display: block !important; 12 | 13 | height: 100%; 14 | height: 100vh; 15 | 16 | overflow: hidden; 17 | 18 | background: rgb(215, 215, 215); 19 | background: -o-radial-gradient(rgb(240, 240, 240), rgb(190, 190, 190)); 20 | background: -moz-radial-gradient(rgb(240, 240, 240), rgb(190, 190, 190)); 21 | background: -webkit-radial-gradient(rgb(240, 240, 240), rgb(190, 190, 190)); 22 | background: -webkit-gradient( 23 | radial, 24 | 50% 50%, 25 | 0, 26 | 50% 50%, 27 | 500, 28 | from(rgb(240, 240, 240)), 29 | to(rgb(190, 190, 190)) 30 | ); 31 | 32 | -webkit-font-smoothing: antialiased; 33 | } 34 | 35 | .slides { 36 | width: 100%; 37 | height: 100%; 38 | left: 0; 39 | top: 0; 40 | 41 | position: absolute; 42 | 43 | -webkit-transform: translate3d(0, 0, 0); 44 | } 45 | 46 | .slides > article { 47 | display: block; 48 | 49 | position: absolute; 50 | overflow: hidden; 51 | 52 | width: 900px; 53 | height: 700px; 54 | 55 | left: 50%; 56 | top: 50%; 57 | 58 | margin-left: -450px; 59 | margin-top: -350px; 60 | 61 | padding: 40px 60px; 62 | 63 | box-sizing: border-box; 64 | -o-box-sizing: border-box; 65 | -moz-box-sizing: border-box; 66 | -webkit-box-sizing: border-box; 67 | 68 | border-radius: 10px; 69 | -o-border-radius: 10px; 70 | -moz-border-radius: 10px; 71 | -webkit-border-radius: 10px; 72 | 73 | background-color: white; 74 | 75 | border: 1px solid rgba(0, 0, 0, 0.3); 76 | 77 | transition: transform 0.3s ease-out; 78 | -o-transition: -o-transform 0.3s ease-out; 79 | -moz-transition: -moz-transform 0.3s ease-out; 80 | -webkit-transition: -webkit-transform 0.3s ease-out; 81 | } 82 | .slides.layout-widescreen > article { 83 | /* margin-left: -550px; 84 | width: 1500px; */ 85 | } 86 | .slides.layout-faux-widescreen > article { 87 | margin-left: -550px; 88 | width: 1100px; 89 | 90 | padding: 40px 160px; 91 | } 92 | 93 | .slides.layout-widescreen > article:not(.nobackground):not(.biglogo), 94 | .slides.layout-faux-widescreen > article:not(.nobackground):not(.biglogo) { 95 | background-position-x: 0, 840px; 96 | } 97 | 98 | /* Clickable/tappable areas */ 99 | 100 | .slide-area { 101 | z-index: 1000; 102 | 103 | position: absolute; 104 | left: 0; 105 | top: 0; 106 | width: 150px; 107 | height: 700px; 108 | 109 | left: 50%; 110 | top: 50%; 111 | 112 | cursor: pointer; 113 | margin-top: -350px; 114 | 115 | tap-highlight-color: transparent; 116 | -o-tap-highlight-color: transparent; 117 | -moz-tap-highlight-color: transparent; 118 | -webkit-tap-highlight-color: transparent; 119 | } 120 | #prev-slide-area { 121 | margin-left: -550px; 122 | } 123 | #next-slide-area { 124 | margin-left: 400px; 125 | } 126 | .slides.layout-widescreen #prev-slide-area, 127 | .slides.layout-faux-widescreen #prev-slide-area { 128 | margin-left: -650px; 129 | } 130 | .slides.layout-widescreen #next-slide-area, 131 | .slides.layout-faux-widescreen #next-slide-area { 132 | margin-left: 500px; 133 | } 134 | 135 | /* Slides */ 136 | 137 | .slides > article { 138 | display: none; 139 | } 140 | .slides > article.far-past { 141 | display: block; 142 | transform: translate(-2040px); 143 | -o-transform: translate(-2040px); 144 | -moz-transform: translate(-2040px); 145 | -webkit-transform: translate3d(-2040px, 0, 0); 146 | } 147 | .slides > article.past { 148 | display: block; 149 | transform: translate(-1020px); 150 | -o-transform: translate(-1020px); 151 | -moz-transform: translate(-1020px); 152 | -webkit-transform: translate3d(-1020px, 0, 0); 153 | } 154 | .slides > article.current { 155 | display: block; 156 | transform: translate(0); 157 | -o-transform: translate(0); 158 | -moz-transform: translate(0); 159 | -webkit-transform: translate3d(0, 0, 0); 160 | } 161 | .slides > article.next { 162 | display: block; 163 | transform: translate(1020px); 164 | -o-transform: translate(1020px); 165 | -moz-transform: translate(1020px); 166 | -webkit-transform: translate3d(1020px, 0, 0); 167 | } 168 | .slides > article.far-next { 169 | display: block; 170 | transform: translate(2040px); 171 | -o-transform: translate(2040px); 172 | -moz-transform: translate(2040px); 173 | -webkit-transform: translate3d(2040px, 0, 0); 174 | } 175 | 176 | .slides.layout-widescreen > article.far-past, 177 | .slides.layout-faux-widescreen > article.far-past { 178 | display: block; 179 | transform: translate(-2260px); 180 | -o-transform: translate(-2260px); 181 | -moz-transform: translate(-2260px); 182 | -webkit-transform: translate3d(-2260px, 0, 0); 183 | } 184 | .slides.layout-widescreen > article.past, 185 | .slides.layout-faux-widescreen > article.past { 186 | display: block; 187 | transform: translate(-1130px); 188 | -o-transform: translate(-1130px); 189 | -moz-transform: translate(-1130px); 190 | -webkit-transform: translate3d(-1130px, 0, 0); 191 | } 192 | .slides.layout-widescreen > article.current, 193 | .slides.layout-faux-widescreen > article.current { 194 | display: block; 195 | transform: translate(0); 196 | -o-transform: translate(0); 197 | -moz-transform: translate(0); 198 | -webkit-transform: translate3d(0, 0, 0); 199 | } 200 | .slides.layout-widescreen > article.next, 201 | .slides.layout-faux-widescreen > article.next { 202 | display: block; 203 | transform: translate(1130px); 204 | -o-transform: translate(1130px); 205 | -moz-transform: translate(1130px); 206 | -webkit-transform: translate3d(1130px, 0, 0); 207 | } 208 | .slides.layout-widescreen > article.far-next, 209 | .slides.layout-faux-widescreen > article.far-next { 210 | display: block; 211 | transform: translate(2260px); 212 | -o-transform: translate(2260px); 213 | -moz-transform: translate(2260px); 214 | -webkit-transform: translate3d(2260px, 0, 0); 215 | } 216 | } 217 | 218 | @media print { 219 | /* Set page layout */ 220 | @page { 221 | size: A4 landscape; 222 | } 223 | 224 | body { 225 | display: block !important; 226 | } 227 | 228 | .slides > article { 229 | display: block; 230 | 231 | position: relative; 232 | 233 | page-break-inside: never; 234 | page-break-after: always; 235 | 236 | overflow: hidden; 237 | } 238 | 239 | h2 { 240 | position: static !important; 241 | margin-top: 400px !important; 242 | margin-bottom: 100px !important; 243 | } 244 | 245 | div.code { 246 | background: rgb(240, 240, 240); 247 | } 248 | 249 | /* Add explicit links */ 250 | a:link:after, 251 | a:visited:after { 252 | content: ' (' attr(href) ') '; 253 | font-size: 50%; 254 | } 255 | 256 | #help { 257 | display: none; 258 | visibility: hidden; 259 | } 260 | } 261 | 262 | /* Styles for full screen mode */ 263 | .slides.fullscreen > article.next, .slides.fullscreen > article.far-next, 264 | .slides.fullscreen > article.past, .slides.fullscreen > article.far-past { 265 | display: none; 266 | } 267 | 268 | /* Styles for slides */ 269 | 270 | .slides > article { 271 | font-family: 'Open Sans', Arial, sans-serif; 272 | 273 | color: black; 274 | text-shadow: 0 1px 1px rgba(0, 0, 0, 0.1); 275 | 276 | font-size: 26px; 277 | line-height: 36px; 278 | 279 | letter-spacing: -1px; 280 | } 281 | 282 | b { 283 | font-weight: 600; 284 | } 285 | 286 | a { 287 | color: rgb(0, 102, 204); 288 | text-decoration: none; 289 | } 290 | a:visited { 291 | color: rgba(0, 102, 204, 0.75); 292 | } 293 | a:hover { 294 | color: black; 295 | } 296 | 297 | p { 298 | margin: 0; 299 | padding: 0; 300 | 301 | margin-top: 20px; 302 | } 303 | p:first-child { 304 | margin-top: 0; 305 | } 306 | 307 | h1 { 308 | font-size: 60px; 309 | line-height: 60px; 310 | 311 | padding: 0; 312 | margin: 0; 313 | margin-top: 200px; 314 | margin-bottom: 5px; 315 | padding-right: 40px; 316 | 317 | font-weight: 600; 318 | 319 | letter-spacing: -3px; 320 | 321 | color: rgb(51, 51, 51); 322 | } 323 | 324 | h2 { 325 | font-size: 45px; 326 | line-height: 45px; 327 | 328 | position: absolute; 329 | bottom: 150px; 330 | 331 | padding: 0; 332 | margin: 0; 333 | padding-right: 40px; 334 | 335 | font-weight: 600; 336 | 337 | letter-spacing: -2px; 338 | 339 | color: rgb(51, 51, 51); 340 | } 341 | 342 | h3 { 343 | font-size: 30px; 344 | line-height: 36px; 345 | 346 | padding: 0; 347 | margin: 0; 348 | padding-right: 40px; 349 | 350 | font-weight: 600; 351 | 352 | letter-spacing: -1px; 353 | 354 | color: rgb(51, 51, 51); 355 | } 356 | 357 | ul { 358 | margin: 0; 359 | padding: 0; 360 | margin-top: 20px; 361 | margin-left: 1.5em; 362 | } 363 | li { 364 | padding: 0; 365 | margin: 0 0 0.5em 0; 366 | } 367 | 368 | div.code { 369 | padding: 5px 10px; 370 | margin-top: 20px; 371 | margin-bottom: 20px; 372 | overflow: hidden; 373 | 374 | background: rgb(240, 240, 240); 375 | border: 1px solid rgb(224, 224, 224); 376 | } 377 | pre { 378 | margin: 0; 379 | padding: 0; 380 | 381 | font-family: 'Droid Sans Mono', 'Courier New', monospace; 382 | font-size: 18px; 383 | line-height: 24px; 384 | letter-spacing: -1px; 385 | 386 | color: black; 387 | } 388 | 389 | pre.numbers span:before { 390 | content: attr(num); 391 | margin-right: 1em; 392 | display: inline-block; 393 | } 394 | 395 | code { 396 | font-size: 95%; 397 | font-family: 'Droid Sans Mono', 'Courier New', monospace; 398 | 399 | padding: .2em .4em; 400 | margin: 0; 401 | font-size: 85%; 402 | background-color: rgba(27,31,35,.05); 403 | border-radius: 6px; 404 | } 405 | 406 | article > .image, 407 | article > .video { 408 | text-align: center; 409 | margin-top: 40px; 410 | } 411 | 412 | article.background { 413 | background-size: contain; 414 | background-repeat: round; 415 | } 416 | 417 | table { 418 | width: 100%; 419 | border-collapse: collapse; 420 | margin-top: 40px; 421 | } 422 | th { 423 | font-weight: 600; 424 | text-align: left; 425 | } 426 | td, 427 | th { 428 | border: 1px solid rgb(224, 224, 224); 429 | padding: 5px 10px; 430 | vertical-align: top; 431 | } 432 | 433 | p.link { 434 | margin-left: 20px; 435 | } 436 | 437 | .pagenumber { 438 | color: #8c8c8c; 439 | font-size: 75%; 440 | position: absolute; 441 | bottom: 0px; 442 | right: 10px; 443 | } 444 | 445 | /* Code */ 446 | div.code { 447 | outline: 0px solid transparent; 448 | } 449 | div.playground { 450 | position: relative; 451 | } 452 | div.output { 453 | position: absolute; 454 | left: 50%; 455 | top: 50%; 456 | right: 40px; 457 | bottom: 40px; 458 | background: #202020; 459 | padding: 5px 10px; 460 | z-index: 2; 461 | 462 | border-radius: 10px; 463 | -o-border-radius: 10px; 464 | -moz-border-radius: 10px; 465 | -webkit-border-radius: 10px; 466 | } 467 | div.output pre { 468 | margin: 0; 469 | padding: 0; 470 | background: none; 471 | border: none; 472 | width: 100%; 473 | height: 100%; 474 | overflow: auto; 475 | } 476 | div.output .stdout, 477 | div.output pre { 478 | color: #e6e6e6; 479 | } 480 | div.output .stderr, 481 | div.output .error { 482 | color: rgb(255, 200, 200); 483 | } 484 | div.output .system, 485 | div.output .exit { 486 | color: rgb(255, 230, 120); 487 | } 488 | .buttons { 489 | position: relative; 490 | float: right; 491 | top: -60px; 492 | right: 10px; 493 | } 494 | div.output .buttons { 495 | position: absolute; 496 | float: none; 497 | top: auto; 498 | right: 5px; 499 | bottom: 5px; 500 | } 501 | 502 | /* Presenter details */ 503 | .presenter { 504 | margin-top: 20px; 505 | } 506 | .presenter p, 507 | .presenter .link { 508 | margin: 0; 509 | font-size: 28px; 510 | line-height: 1.2em; 511 | } 512 | 513 | /* Output resize details */ 514 | .ui-resizable-handle { 515 | position: absolute; 516 | } 517 | .ui-resizable-n { 518 | cursor: n-resize; 519 | height: 7px; 520 | width: 100%; 521 | top: -5px; 522 | left: 0; 523 | } 524 | .ui-resizable-w { 525 | cursor: w-resize; 526 | width: 7px; 527 | left: -5px; 528 | top: 0; 529 | height: 100%; 530 | } 531 | .ui-resizable-nw { 532 | cursor: nw-resize; 533 | width: 9px; 534 | height: 9px; 535 | left: -5px; 536 | top: -5px; 537 | } 538 | iframe { 539 | border: none; 540 | } 541 | figcaption { 542 | color: #666; 543 | text-align: center; 544 | font-size: 0.75em; 545 | } 546 | 547 | #help { 548 | font-family: 'Open Sans', Arial, sans-serif; 549 | text-align: center; 550 | color: white; 551 | background: #000; 552 | opacity: 0.5; 553 | position: fixed; 554 | bottom: 25px; 555 | left: 50px; 556 | right: 50px; 557 | padding: 20px; 558 | 559 | border-radius: 10px; 560 | -o-border-radius: 10px; 561 | -moz-border-radius: 10px; 562 | -webkit-border-radius: 10px; 563 | } 564 | 565 | .slide-area { 566 | display: none; 567 | } 568 | 569 | .emphasize { 570 | color: red; 571 | font-weight: bold; 572 | } 573 | 574 | blockquote { 575 | background: #f9f9f9; 576 | border-left: 10px solid #ccc; 577 | margin: 1.5em 10px; 578 | padding: 0.5em 10px; 579 | } 580 | blockquote:before { 581 | color: #ccc; 582 | font-size: 4em; 583 | line-height: 0.1em; 584 | margin-right: 0.25em; 585 | vertical-align: -0.4em; 586 | } 587 | blockquote p { 588 | display: inline; 589 | } 590 | -------------------------------------------------------------------------------- /theme/templates/action.tmpl: -------------------------------------------------------------------------------- 1 | {/* 2 | This is the action template. 3 | It determines how the formatting actions are rendered. 4 | */} 5 | 6 | {{define "section"}} 7 |{{range .Lines}}{{.}}{{end}}
24 | {{range $i, $l := .Lines}}{{if $i}}{{template "newline"}} 25 | {{end}}{{style $l}}{{end}} 26 |
27 | {{end}} 28 | {{end}} 29 | 30 | {{define "code"}} 31 |