github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/talks/2014/taste.slide (about) 1 A Taste of Go 2 August 14, 2014 3 4 Robert Griesemer 5 Google 6 gri@golang.org 7 8 9 * The Go programming language 10 11 - Modern 12 # OO support but not type-oriented 13 # strong support for concurrency 14 - Compact, concise, general-purpose 15 - Imperative, statically type-checked, dynamically type-safe 16 - Garbage-collected 17 - Compiles to native code, statically linked 18 - Fast compilation, efficient execution 19 20 Designed by programmers for programmers! 21 22 23 * Hello, World! 24 25 .play taste/hello.go 26 27 # Unicode 28 # Programs are organized in packages 29 # A package is a set of package files 30 # A package file expresses its dependencies on other packages via import declarations 31 # The remainder of a package file is a list of (constant, variable, type, and function) declarations 32 33 34 * Hello, World! Internet-style 35 36 .play taste/hellohttp.go 37 38 39 * Program elements 40 41 * Constants 42 43 - Maintained precisely: 44 const e = 2.71828182845904523536028747135266249775724709369995957496696763 45 const third = 1.0/3 46 - Typed or without type: 47 const M64 int64 = 1<<20 48 const M = 1<<20 49 - Evaluated at compile-time: 50 const big = 1<<100 / 1e30 // valid constant expression 51 52 Compiler complains if a constant doesn't fit where it is _used_. 53 54 55 * Variables 56 57 - Statically typed: 58 var x int 59 var s, t string 60 - Implicitly or explicitly initialized: 61 var x int 62 var s, t string = "foo", "bar" // multiple assignment 63 64 var x = 42 // int 65 var s, b = "foo", true // string, bool 66 - Short variable declaration (inside functions only): 67 x := 42 68 s, b := "foo", true 69 - Can safely take address of _any_ variable! 70 return &x 71 # compiler will do the right thing 72 73 74 * Types 75 76 - Predeclared types, the usual suspects: 77 uint8 (byte), uint16, uint32, uint32, uint64, 78 int8, int16, int32, int32 (rune), int64, 79 float32, float64, 80 complex64, complex128, 81 uint, int, uintptr, 82 bool, string, 83 error // not so usual 84 85 - Composite types: 86 array, struct, pointer, function, 87 slice, map, channel 88 89 - Abstract type: 90 interface 91 92 93 * Type declarations 94 95 - Composition from left-to-right (Pascal style): 96 [10]byte // array of 10 bytes 97 98 struct { 99 name string 100 left, right *Node 101 action func(*Node) 102 } 103 104 func(a, b, c int) 105 func(http.ResponseWriter, *http.Request) error 106 107 - A type declaration defines a _new_ type: 108 type Weekday int 109 110 type Point struct { 111 x, y int 112 } 113 114 115 * Slices 116 117 []T // slice of T 118 119 - Descriptor for an underlying array segment 120 - May grow and shrink 121 - Has length and capacity 122 - Assigning a slice copies the descriptor, not the underlying array 123 124 Common slice operations: 125 126 len(s) 127 s[i] 128 s[i:j] 129 append(s, x) // append element x to slice s and return new slice 130 131 - Slices play the role of dynamically sized arrays 132 - Widely used in Go code 133 134 135 * Maps 136 137 map[K]V // map K -> V 138 139 - Map is a language-supplied hash table 140 - Maps values of key type K to values of type V 141 - Assigning a map copies the map reference, not the map contents 142 143 Common map operations: 144 145 make(map[K]V) 146 len(m) 147 m[k] 148 delete(m, k) 149 150 - Map iteration order is not specified: 151 152 for key, value := range m { 153 // order of key sequence different each time 154 } 155 156 * Statements 157 158 - Curly braces (C style) 159 - Multiple assignments and some other new constructs 160 - Many cleanups: mandatory braces, no parentheses for conditionals, implicit break in switches, no semicolons, etc. 161 a, b = b, a // swap 162 f, err = os.Open(filename) 163 164 if x < y { 165 return x 166 } else { 167 return y 168 } 169 170 switch day { 171 case Mon: 172 ... 173 // break is implicit 174 case Tue, Wed: 175 ... 176 } 177 178 179 * A few words on syntax 180 181 _Syntax_doesn't_matter_unless_you_are_a_programmer._ 182 -- Rob Pike 183 184 Corollary: 185 186 _Compactness_of_syntax_doesn't_matter_unless_you_are_reading_programs._ 187 188 Compact is not the same as terse. Readability is crucial. 189 190 191 * An example: IndexOfAny in Java 192 193 public static int IndexOfAny(String str, char[] chars) { 194 if (isEmpty(str) || ArrayUtils.isEmpty(chars)) { 195 return -1; 196 } 197 for (int i = 0; i < str.length(); i++) { 198 char ch = str.charAt(i); 199 for (int j = 0; j < chars.length; j++) { 200 if (chars[j] == ch) { 201 return i; 202 } 203 } 204 } 205 return -1; 206 } 207 208 299 chars (100%), 101 tokens (100%) 209 210 211 * IndexOfAny in Go 212 213 .code taste/examples.go /IndexOfAny START/,/IndexOfAny END/ 214 215 217 chars (73%), 62 tokens (61%) 216 217 Almost 30% less text and a surprising 40% fewer tokens to read! 218 219 _Less_clutter_means_reduced_cognitive_load._ 220 221 # minimum improvement 222 # typical Go programs tend to require much less than 70% of the code size of equivalent programs in other languages 223 224 225 * Functions 226 227 - Regular functions 228 func Sin(x float64) float64 229 func AddScale(x, y int, f float64) int 230 231 - Multiple return values 232 func Write(data []byte) (written int, err error) 233 234 - Variadic parameter lists without magic 235 func Printf(format string, args ...interface{}) 236 237 - Functions are first-class values 238 var delta int 239 return func(x int) int { return x + delta } 240 241 242 * Function values: An example 243 244 // walkStdLib calls f with the filename of each .go 245 // file in the std library until f return false. 246 func walkStdLib(f func(filename string) bool) 247 248 Calling walkStdLib with a closure: 249 250 .code taste/walk.go /example START/,/example END/ 251 252 More directly: 253 254 .play taste/walk.go /main START/,/main END/ 255 256 257 * Methods 258 259 Methods are functions with a _receiver_ parameter: 260 261 .code taste/point.go /String START/,/String END/ 262 263 The receiver binds the method to its _base_type_ (Point): 264 265 .code taste/point.go /Point START/,/Point END/ 266 267 Methods are invoked via the usual dot notation: 268 269 .play taste/point.go /main START/,/main END/ 270 271 272 * Methods can be defined for any user-defined type! 273 274 For the Weekday type: 275 276 .code taste/weekday.go /type START/,/type END/ 277 278 Define String method on Weekday: 279 280 .code taste/weekday.go /String START/,/String END/ 281 282 .play taste/weekday.go /main START/,/main END/ 283 284 Method calls via non-interface types are statically dispatched. 285 286 * Interface types 287 288 - Abstract 289 - Define (possibly empty) set of method signatures 290 - Values of _any_type_ that implement all methods of an interface can be assigned to a variable of that interface. 291 292 Examples: 293 294 interface{} // empty interface 295 296 interface { 297 String() string 298 } 299 300 interface { 301 Len() int 302 Swap(i, j int) 303 Less(i, j int) bool 304 } 305 306 307 * Using interfaces 308 309 .code taste/stringer.go /Stringer START/,/Stringer END/ 310 311 Both Weekday and Point define a String method, so values of both can be assigned to 312 a variable of Stringer type: 313 314 .play taste/stringer.go /main START/,/main END/ 315 316 Method calls via interface types are dynamically dispatched ("virtual function call"). 317 318 319 * A larger example 320 321 322 * Top 10 identifiers in std library 323 324 .code taste/idents.go 325 326 $ cat $(find $GOROOT -name '*.go') | ./idents | sort | uniq -c | sort -nr | sed 10q 327 328 329 * A variation: Histogram of Go statements 330 331 A histogram is a map from statement name ("if", "for", etc.) to use count: 332 333 .code taste/histo0.go /histogram START/,/histogram END/ 334 335 Algorithm: 336 337 - Use walkStdLib to traverse all files of the std library 338 - For each file, parse and create abstract syntax tree 339 - Traverse syntax tree and add each statement to histogram 340 - Print the result 341 342 .code taste/histo0.go /main START/,/main END/ 343 344 345 * Processing a Go source file 346 347 .code taste/histo0.go /add START/,/add END/ 348 349 350 * Printing the histogram 351 352 .play taste/histo0.go /print START/,/print END/ 353 354 Note: Histogram (map) iteration order is not specified. 355 356 * Sorting 357 358 sort.Sort operates on any type that implements the sort.Interface: 359 360 interface { 361 Len() int 362 Swap(i, j int) 363 Less(i, j int) bool 364 } 365 366 For instance, to sort a slice of strings lexically, define: 367 368 .code taste/sort.go /lexical START/,/lexical END/ 369 370 And sort: 371 372 sort.Sort(lexical(s)) // where s is a []string slice 373 374 375 * Sorting histogram entries 376 377 .code taste/histo.go /byCount START/,/byCount END/ 378 379 380 * Improved histogram printing 381 382 .play taste/histo.go /print START/,/print END/ 383 384 385 * Concurrency 386 387 * Goroutines 388 389 - The _go_ statement launches a function call as a goroutine 390 go f() 391 go f(x, y, ...) 392 393 - A goroutine runs concurrently (but not necessarily in parallel) 394 - A goroutine has its own stack 395 396 397 * A simple example 398 399 .code taste/concurrency1.go /f START/,/f END/ 400 401 Function f is launched as 3 different goroutines, all running concurrently: 402 403 .play taste/concurrency1.go /main START/,/main END/ 404 405 406 * Communication via channels 407 408 A channel type specifies a channel value type (and possibly a communication direction): 409 410 chan int 411 chan<- string // send-only channel 412 <-chan T // receive-only channel 413 414 A channel is a variable of channel type: 415 416 var ch chan int 417 ch := make(chan int) // declare and initialize with newly made channel 418 419 A channel permits _sending_ and _receiving_ values: 420 421 ch <- 1 // send value 1 on channel ch 422 x = <-ch // receive a value from channel ch (and assign to x) 423 424 Channel operations synchronize the communicating goroutines. 425 426 * Communicating goroutines 427 428 Each goroutine sends its results via channel ch: 429 430 .code taste/concurrency2.go /f START/,/f END/ 431 432 The main goroutine receives (and prints) all results from the same channel: 433 434 .play taste/concurrency2.go /main START/,/main END/ 435 436 437 * Putting it all together 438 439 440 * Analyze files concurrently, map-reduce style 441 442 Mapper: 443 444 .code taste/histop.go /mapper START/,/mapper END/ 445 446 Reducer: 447 448 .code taste/histop.go /reducer START/,/reducer END/ 449 450 .code taste/histop.go /merge START/,/merge END/ 451 452 453 * From sequential program... 454 455 .play taste/histo.go /main START/,/main END/ 456 457 458 * ... to concurrent program 459 460 .play taste/histop.go /main START/,/main END/ 461 462 463 * There's a lot more! 464 465 - Extensive standard library 466 467 .link http://golang.org/pkg/ 468 469 - Powerful tools 470 471 .link http://play.golang.org/p/Au02fFpYdf 472 # playground, gofmt 473 474 - Multi-platform support 475 476 .link http://build.golang.org/ 477 478 - Great documentation 479 480 .link http://tour.golang.org/#1