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