go程序设计语言-第一章 入门(1)

1、命令行输入

os.Args是一个字符串切片,是半开区间,通过os.Args[i]来访问元素;如果变量未在声明的时候初始化,将隐式的初始化为这个类型的空值;

操作符 += 是个赋值操作符;

i++ 是一个语句不是表达式;

for是go唯一的循环:

for initialization; condition; post {
    //零个或多个语句
}

三个部分都是可以省略的

//传统的while循环
for condition {
    // ...
}
//传统的无限循环
for {
    // ...
}

//for range循环
for key, value := range os.Args[1:] {
    // ...
}

循环可以通过break或者return结束;

空标识符 _ 表示丢弃临时变量;

//变量的声明方式

s := ""
var s string
var s = ""
var s string = ""

strings.Join( s []string, " " )

2、找出重复的行

package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	counts := make(map[string]int)
	input := bufio.NewScanner(os.Stdin)
	for input.Scan() {

		if input.Text() != "EOF" {
			counts[input.Text()]++
		} else {
			break
		}

	}
	for line, n := range counts {
		if n > 1 {
			fmt.Printf("%d\t%s\n", n, line)
		}
	}
}

map存储一个键值对组合,键可以是一个进行==比较的任意类型,值可以是任意类型,内置函数make可以用来新建map;

printf转义字符verb

verb    描述
%d %x %o %b十、十六、八、二进制整数
%f %g %e浮点数
%t布尔型
%c %s %q %v %T %%字符、字符串、带引号的字符串、任何值、值类型、百分号本身

以f结尾的函数,使用和printf相同的格式化规则,以ln结尾的函数,使用%v来格式化参数

输入输出函数bufio.Scanner, ioutil.Readfile,ioutil.WriteFile使用*os.File中的Read和write方法

3、gif动画

package main

import (
	"image"
	"image/color"
	"image/gif"
	"io"
	"log"
	"math"
	"math/rand"
	"net/http"
	"os"
	"time"
)

var palette = []color.Color{color.White, color.Black}

const (
	whiteIdex = 0
	blackIdex = 1
)

func main() {
	rand.Seed(time.Now().UTC().UnixNano())
	if len(os.Args) > 1 && os.Args[1] == "web" {
		handler := func(w http.ResponseWriter, r *http.Request) {
			lissajous(w)
		}
		http.HandleFunc("/", handler)
		log.Fatal(http.ListenAndServe("localhost:8000", nil))
		return
	}

	lissajous(os.Stdout)

}

func lissajous(out io.Writer) {
	const (
		cycles  = 5
		res     = 0.001
		size    = 100
		nframes = 64
		delay   = 8
	)

	freq := rand.Float64() * 3.0
	anim := gif.GIF{LoopCount: nframes}
	phase := 0.0
	for i := 0; i < nframes; i++ {
		rect := image.Rect(0, 0, 2*size+1, 2*size+1)
		img := image.NewPaletted(rect, palette)
		for t := 0.0; t < cycles*2*math.Pi; t += res {
			x := math.Sin(t)
			y := math.Sin(t*freq + phase)
			img.SetColorIndex(size+int(x*size+0.5), size+int(y*size+0.5), blackIdex)
		}
		phase += 0.1
		anim.Delay = append(anim.Delay, delay)
		anim.Image = append(anim.Image, img)
	}
	gif.EncodeAll(out, &anim)
}
package main

import (
	"image"
	"image/color"
	"image/gif"
	"io"
	"log"
	"math"
	"math/rand"
	"net/http"
	"os"
	"time"
)

var palette = []color.Color{color.White, color.Black}

const (
	whiteIdex = 0
	blackIdex = 1
)

func main() {
	rand.Seed(time.Now().UTC().UnixNano())
	if len(os.Args) > 1 && os.Args[1] == "web" {
		handler := func(w http.ResponseWriter, r *http.Request) {
			lissajous(w)
		}
		http.HandleFunc("/", handler)
		log.Fatal(http.ListenAndServe("localhost:8000", nil))
		return
	}

	lissajous(os.Stdout)

}

func lissajous(out io.Writer) {
	const (
		cycles  = 5
		res     = 0.001
		size    = 100
		nframes = 64
		delay   = 8
	)

	freq := rand.Float64() * 3.0
	anim := gif.GIF{LoopCount: nframes}
	phase := 0.0
	for i := 0; i < nframes; i++ {
		rect := image.Rect(0, 0, 2*size+1, 2*size+1)
		img := image.NewPaletted(rect, palette)
		for t := 0.0; t < cycles*2*math.Pi; t += res {
			x := math.Sin(t)
			y := math.Sin(t*freq + phase)
			img.SetColorIndex(size+int(x*size+0.5), size+int(y*size+0.5), blackIdex)
		}
		phase += 0.1
		anim.Delay = append(anim.Delay, delay)
		anim.Image = append(anim.Image, img)
	}
	gif.EncodeAll(out, &anim)
}

[]color.Color{...}  gif.GIF{...}是复合字面量,用一系列元素的值初始化go的复合类型的紧凑表达式

结构体的字段可以使用点标记法来访问

4、获取一个url

package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
)

func main() {
	for _, url := range os.Args[1:] {
		resp, err := http.Get(url)
		if err != nil {
			fmt.Fprintf(os.Stderr, "fetch: %v\n", err)
			os.Exit(1)
		}
		bytes, err := ioutil.ReadAll(resp.Body)
		resp.Body.Close()
		if err != nil {
			fmt.Fprintf(os.Stderr, "reading: %v\n", err)
			os.Exit(1)
		}
		fmt.Printf("%s", string(bytes))
	}
}

 resp.body.close()关闭body数据流来避免资源泄露

5、并发获取多个url

package main

import (
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"time"
)

func main() {

	start := time.Now()
	ch := make(chan string)
	for _, url := range os.Args[1:] {
		go fetch(url, ch)
	}

	for range os.Args[1:] {
		fmt.Println(<-ch) //从通道ch接收值
	}
	fmt.Printf("%.2fs elapsed\n", time.Since(start).Seconds())

}

func fetch(url string, ch chan<- string) {
	start := time.Now()
	resp, err := http.Get(url)
	if err != nil {
		ch <- fmt.Sprint(err)
		return
	}
	nbytes, err := io.Copy(ioutil.Discard, resp.Body)
	resp.Body.Close()
	if err != nil {
		ch <- fmt.Sprintf("while reading %s : %v\n", url, err)
		return
	}

	secs := time.Since(start).Seconds()
	ch <- fmt.Sprintf("%.2fs %7d %s", secs, nbytes, url)
}

io.copy读取响应的内容,并写入ioutil.discard输出流进行丢弃;当一个goroutie在一个通道上进行发送或接受操作时,会阻塞,直到另个goroutie进行对通道接受或发送值

6、一个web服务器

package main

import (
	"fmt"
	"log"
	"net/http"
)

func main() {
	http.HandleFunc("/", handler)
	log.Fatal(http.ListenAndServe("localhost:80", nil))
}

func handler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "URL.PATH = %q\n", r.URL.Path)
}

匿名函数

package main

import (
	"fmt"
	"log"
	"net/http"
)

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request){
    fmt.Fprintf(w, "URL.PATH = %q\n", r.URL.Path)
}
	log.Fatal(http.ListenAndServe("localhost:80", nil))
}

fetch将程序响应os.stdout,fetchall将程序响应复制到ioutil.discard进行丢弃,web服务器使用fprintf写入http.responsWriter让浏览器显示,三者都满足接口io.Writer,按需将使用任何一种输出流;

7、其他

switch第一个匹配的case执行,否则执行default,fallthrough是个例外。也可以没有操作数,每条case都是布尔表达式等价于switch true。

**breake可以打断for, switch, select 最内层调用,开始执行下面语句。

**continue可以让for循环开始新的迭代

命名类型、指针也称引用。

方法和接口

所以,开始go的旅程吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值