Source file doc/progs/go1.go

     1  // Copyright 2011 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  // This file contains examples to embed in the Go 1 release notes document.
     6  
     7  package main
     8  
     9  import (
    10  	"errors"
    11  	"flag"
    12  	"fmt"
    13  	"log"
    14  	"os"
    15  	"path/filepath"
    16  	"testing"
    17  	"time"
    18  	"unicode"
    19  )
    20  
    21  func main() {
    22  	flag.Parse()
    23  	stringAppend()
    24  	mapDelete()
    25  	mapIteration()
    26  	multipleAssignment()
    27  	structEquality()
    28  	compositeLiterals()
    29  	runeType()
    30  	errorExample()
    31  	timePackage()
    32  	walkExample()
    33  	osIsExist()
    34  }
    35  
    36  var timeout = flag.Duration("timeout", 30*time.Second, "how long to wait for completion")
    37  
    38  func init() {
    39  	// canonicalize the logging
    40  	log.SetFlags(0)
    41  }
    42  
    43  func mapDelete() {
    44  	m := map[string]int{"7": 7, "23": 23}
    45  	k := "7"
    46  	delete(m, k)
    47  	if m["7"] != 0 || m["23"] != 23 {
    48  		log.Fatal("mapDelete:", m)
    49  	}
    50  }
    51  
    52  func stringAppend() {
    53  	greeting := []byte{}
    54  	greeting = append(greeting, []byte("hello ")...)
    55  	greeting = append(greeting, "world"...)
    56  	if string(greeting) != "hello world" {
    57  		log.Fatal("stringAppend: ", string(greeting))
    58  	}
    59  }
    60  
    61  func mapIteration() {
    62  	m := map[string]int{"Sunday": 0, "Monday": 1}
    63  	for name, value := range m {
    64  		// This loop should not assume Sunday will be visited first.
    65  		f(name, value)
    66  	}
    67  }
    68  
    69  func f(string, int) {
    70  }
    71  
    72  func assert(t bool) {
    73  	if !t {
    74  		log.Panic("assertion fail")
    75  	}
    76  }
    77  
    78  func multipleAssignment() {
    79  	sa := []int{1, 2, 3}
    80  	i := 0
    81  	i, sa[i] = 1, 2 // sets i = 1, sa[0] = 2
    82  
    83  	sb := []int{1, 2, 3}
    84  	j := 0
    85  	sb[j], j = 2, 1 // sets sb[0] = 2, j = 1
    86  
    87  	sc := []int{1, 2, 3}
    88  	sc[0], sc[0] = 1, 2 // sets sc[0] = 1, then sc[0] = 2 (so sc[0] = 2 at end)
    89  
    90  	assert(i == 1 && sa[0] == 2)
    91  	assert(j == 1 && sb[0] == 2)
    92  	assert(sc[0] == 2)
    93  }
    94  
    95  func structEquality() {
    96  	type Day struct {
    97  		long  string
    98  		short string
    99  	}
   100  	Christmas := Day{"Christmas", "XMas"}
   101  	Thanksgiving := Day{"Thanksgiving", "Turkey"}
   102  	holiday := map[Day]bool{
   103  		Christmas:    true,
   104  		Thanksgiving: true,
   105  	}
   106  	fmt.Printf("Christmas is a holiday: %t\n", holiday[Christmas])
   107  }
   108  
   109  func compositeLiterals() {
   110  	type Date struct {
   111  		month string
   112  		day   int
   113  	}
   114  	// Struct values, fully qualified; always legal.
   115  	holiday1 := []Date{
   116  		Date{"Feb", 14},
   117  		Date{"Nov", 11},
   118  		Date{"Dec", 25},
   119  	}
   120  	// Struct values, type name elided; always legal.
   121  	holiday2 := []Date{
   122  		{"Feb", 14},
   123  		{"Nov", 11},
   124  		{"Dec", 25},
   125  	}
   126  	// Pointers, fully qualified, always legal.
   127  	holiday3 := []*Date{
   128  		&Date{"Feb", 14},
   129  		&Date{"Nov", 11},
   130  		&Date{"Dec", 25},
   131  	}
   132  	// Pointers, type name elided; legal in Go 1.
   133  	holiday4 := []*Date{
   134  		{"Feb", 14},
   135  		{"Nov", 11},
   136  		{"Dec", 25},
   137  	}
   138  	// STOP OMIT
   139  	_, _, _, _ = holiday1, holiday2, holiday3, holiday4
   140  }
   141  
   142  func runeType() {
   143  	l            // STARTRUNE OMIT
   144  	delta := 'δ' // delta has type rune.
   145  	var DELTA rune
   146  	DELTA = unicode.ToUpper(delta)
   147  	epsilon := unicode.ToLower(DELTA + 1)
   148  	if epsilon != 'δ'+1 {
   149  		log.Fatal("inconsistent casing for Greek")
   150  	}
   151  	// ENDRUNE OMIT
   152  }
   153  
   154  // START ERROR EXAMPLE OMIT
   155  type SyntaxError struct {
   156  	File    string
   157  	Line    int
   158  	Message string
   159  }
   160  
   161  func (se *SyntaxError) Error() string {
   162  	return fmt.Sprintf("%s:%d: %s", se.File, se.Line, se.Message)
   163  }
   164  
   165  // END ERROR EXAMPLE OMIT
   166  
   167  func errorExample() {
   168  	var ErrSyntax = errors.New("syntax error")
   169  	_ = ErrSyntax
   170  	se := &SyntaxError{"file", 7, "error"}
   171  	got := fmt.Sprint(se)
   172  	const expect = "file:7: error"
   173  	if got != expect {
   174  		log.Fatalf("errorsPackage: expected %q got %q", expect, got)
   175  	}
   176  }
   177  
   178  // sleepUntil sleeps until the specified time. It returns immediately if it's too late.
   179  func sleepUntil(wakeup time.Time) {
   180  	now := time.Now() // A Time.
   181  	if !wakeup.After(now) {
   182  		return
   183  	}
   184  	delta := wakeup.Sub(now) // A Duration.
   185  	fmt.Printf("Sleeping for %.3fs\n", delta.Seconds())
   186  	time.Sleep(delta)
   187  }
   188  
   189  func timePackage() {
   190  	sleepUntil(time.Now().Add(123 * time.Millisecond))
   191  }
   192  
   193  func walkExample() {
   194  	// STARTWALK OMIT
   195  	markFn := func(path string, info os.FileInfo, err error) error {
   196  		if path == "pictures" { // Will skip walking of directory pictures and its contents.
   197  			return filepath.SkipDir
   198  		}
   199  		if err != nil {
   200  			return err
   201  		}
   202  		log.Println(path)
   203  		return nil
   204  	}
   205  	err := filepath.Walk(".", markFn)
   206  	if err != nil {
   207  		log.Fatal(err)
   208  	}
   209  	// ENDWALK OMIT
   210  }
   211  
   212  func initializationFunction(c chan int) {
   213  	c <- 1
   214  }
   215  
   216  var PackageGlobal int
   217  
   218  func init() {
   219  	c := make(chan int)
   220  	go initializationFunction(c)
   221  	PackageGlobal = <-c
   222  }
   223  
   224  func BenchmarkSprintf(b *testing.B) {
   225  	// Verify correctness before running benchmark.
   226  	b.StopTimer()
   227  	got := fmt.Sprintf("%x", 23)
   228  	const expect = "17"
   229  	if expect != got {
   230  		b.Fatalf("expected %q; got %q", expect, got)
   231  	}
   232  	b.StartTimer()
   233  	for i := 0; i < b.N; i++ {
   234  		fmt.Sprintf("%x", 23)
   235  	}
   236  }
   237  
   238  func osIsExist() {
   239  	name := "go1.go"
   240  	f, err := os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600)
   241  	if os.IsExist(err) {
   242  		log.Printf("%s already exists", name)
   243  	}
   244  	_ = f
   245  }
   246  
   247  func closeExample() {
   248  	// STARTCLOSE OMIT
   249  	var c chan int
   250  	var csend chan<- int = c
   251  	var crecv <-chan int = c
   252  	close(c)     // legal
   253  	close(csend) // legal
   254  	close(crecv) // illegal
   255  	// ENDCLOSE OMIT
   256  }
   257  
   258  func Bug() (i, j, k int) {
   259  	for i = 0; i < 5; i++ {
   260  		for j := 0; j < 5; j++ { // Redeclares j.
   261  			k += i * j
   262  			if k > 100 {
   263  				return // Rejected: j is shadowed here.
   264  			}
   265  		}
   266  	}
   267  	return // OK: j is not shadowed here.
   268  }
   269  

View as plain text