美文网首页
go编程笔记--入门篇

go编程笔记--入门篇

作者: 奶爸撸代码 | 来源:发表于2019-02-24 22:59 被阅读7次

go语言编程笔记--入门篇

Hello world

//hello.go
package main

import "fmt"

func main(){
    str := "hello 世界"
    for _, v := range str {
        fmt.Printf("%c ",  v)
    }
}

此处入门代码不只是简单的fmt.Println("Hello world!"),有以下几点需要注意:

  • main函数包名package main
  • 导入包import "fmt",注意引号
  • go天然支持unicode, 打印非英文的hello world, Printf中的%...称为verb, %c表示打印字符(rune, Unicode码点)
  • 用range for自动识别有效value, 如果打印index,会发现一共8次循环(0~5,6,9), 因为汉字占3个字节
  • 用这种方式可以打印世界各种语言unicode编码字符集

echo命令行

package main
import (
    "os"
    "fmt"
    "strings"
)

func main() {
    var sep, s string
    for _, v := range os.Args[1:] {
        s += sep + v
        sep = " "
    }

    fmt.Println(s)
    // 直接打印,使用strings包的Join
    fmt.Println(strings.Join(os.Args[1:], " "))
}

  • 第一个for循环中s+= sep + v有一个技巧, 最初的seq为零值, 统一处理,避免多一个空格的问题
  • os包的命令行参数
  • strings包处理字符串, Join把slice中元素连接成一个字符串

查找重复行

package reader

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

func main() {
    input := bufio.NewScanner(os.Stdin)
    counter := make(map[string]int, 0)

    for input.Scan() {
        if input.Text()=="q" {
            break
        }
        counter[input.Text()]++
    }

    for k, v := range counter {
        if v > 1 {
            fmt.Println(k)
        }
    }
}

统计有重复的行并打印,主要借助map统计

  • map使用make创建的一个引用, 键只要可以施加==比较即可
  • map的每次迭代顺序随机,因为程序无法保证map迭代的顺序
  • bufio包处理输入和输出方便又高效.Scanner读取输入并将其拆成行或单词
  • 从文件读取可以os.Open(filename)-->*os.File, 或这用ioutil.ReadFile(filename)-->返回一个字节切片(byte slice读取全文
  • 常见转义格式字符
verb comments
%d 十进制整数
%x, %o, %b 十六进制, 八进制, s二进制整数
%f, %g, %e 浮点数: 3.141593 3.141592653589793 3.141593e+00
%t 布尔:true或false
%c 字符(rune) (Unicode码点)
%s 字符串
%q 带双引号的字符串"abc"或带单引号的字符'c'
%v 变量的自然形式(natural format)
%T 变量的类型
%% 字面上的百分号标志(无操作数)

flag包, 解析命令行

package main
import "flag"
func main(){
    strFlag := flag.String("key", "default_value", "comments of the flag")
    flag.Parse()
    print(*strFlag)
}
  • flag.String()/Int/Bool等返回的是指针,对应变量版本flag.StringVar(&varname,xxx)
  • docker使用的cli是非常棒的第三方包

获取url

package networker

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

func main() {
    for _, url := range os.Args[1:] {
        url:=url
        go func(){
            resp, err := http.Get(url)
            if err != nil {
                os.Exit(1)
            }
            b, err := ioutil.ReadAll(resp.Body)
            defer resp.Body.Close()
            if err != nil {
                os.Exit(1)
            }
            fmt.Println(string(b))
        }()
    }
}

  • 使用goroutine并发发送Get请求(net/http)
  • Body是一个io.ReadCloser对象,即实现了io.Reader跟io.Closer接口的对象
  • ioutil.ReadAll读取resp中的Body全部内容
  • url:=url声明局部变量, 以防多个goroutine产生数据竞争

web server

package main

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

var mu sync.Mutex
var cnt int

func main() {
    http.HandleFunc("/", handler)
    http.HandleFunc("/count", counter)
    //http.HandleFunc("/", handler) // each request calls handler
    log.Fatal(http.ListenAndServe("localhost:8000", nil))
}

// handler echoes the Path component of the request URL r.
func handler(w http.ResponseWriter, r *http.Request) {
    mu.Lock()
    cnt++ // 访问次数统计
    mu.Unlock()

    fmt.Fprintf(w, "%s %s %s\n", r.Method, r.URL, r.Proto)
    for k, v := range r.Header {
        fmt.Fprintf(w, "Header[%q] = %q\n", k, v)
    }
    fmt.Fprintf(w, "Host = %q\n", r.Host)
    fmt.Fprintf(w, "RemoteAddr = %q\n", r.RemoteAddr)
    if err := r.ParseForm(); err != nil {
        log.Print(err)
    }
    for k, v := range r.Form {
        fmt.Fprintf(w, "Form[%q] = %q\n", k, v)
    }
}

func counter(w http.ResponseWriter, r *http.Request) {
    mu.Lock()
    fmt.Fprintf(w, "Count %d\n", cnt)
    mu.Unlock()
}
  • /开头的请求为发送到当前站点上的所有请求,监听8000端口
  • handler实现接口func(ResponseWriter, *Request)
  • sync.Mutex互斥量并发控制增加访问计数
  • 此示例打印了许多request相关信息,后续有详解

switch 跟无tag switch

switch coinflip() {
case "heads":
    heads++
case "tails":
    tails++
default:
    fmt.Println("landed on edge!")
}

func Signum(x int) int {
    switch {
    case x > 0:
        return +1
    default:
        return 0
    case x < 0:
        return -1
    }
}

reference

相关文章

  • go编程笔记--入门篇

    go语言编程笔记--入门篇 Hello world 此处入门代码不只是简单的fmt.Println("Hello ...

  • 笨办法学golang(二)

    这是Go语言学习笔记的第二篇文章。 Go语言学习笔记参考书籍「Go语言编程」、Go官方标准库 前文提要 上篇文章中...

  • Golang聚合

    教程 Go Web 编程Go语言圣经(中文版) Tips Golang 学习笔记——交叉编译 & 部署Golang...

  • Go语言下的线程模型

    阅读Go并发编程对go语言线程模型的笔记,解释的非常到,好记性不如烂笔头,忘记的时候回来翻一番,在此做下笔记。 G...

  • Go语言编程笔记

    1.第1章 初识Go语言 介绍了好多工具,我这里使用sublime text3 + window的go1.4进行学...

  • go web 编程笔记

    函数 go函数接受变参func x(arg ...init)int {} defer defer 会按照后进先出的...

  • go核心编程笔记

  • go并发编程笔记

    并发编程 一、并发编程的相关概念1、并发编程概念:使多个任务【程序】可以在同一时间执行以便能够更快的得到结果2、多...

  • Go知识随记

    教程: Go编程时光 — Go编程时光 1.0.0 documentation (iswbm.com)[https...

  • Golang 学习笔记(05)—— 面向对象编程

    本文为转载,原文:Golang 学习笔记(05)—— 面向对象编程 前言 golang是面向过程的语言,go中没有...

网友评论

      本文标题:go编程笔记--入门篇

      本文链接:https://www.haomeiwen.com/subject/sveiyqtx.html