golang的基本语法
最近又打算玩玩golang,打算把工作中的爬虫从脚本语言迁移到golang,读了两本golang的书,对语法做了一个简单的整理。
编程语言的选择
0 业务的要求
1 性能
2 表达能力
3 是否容易上手
4 坑和维护
变量
变量的声明
var xx type 或者 var (xx type xxx type)
初始化
var v1 i = 10; var v2 = 10; v3 := 10
交换值
i,j = j,i
多个值
_,a = 11,34
常量
const pi float32 = 1.2
const zero = 11
const( a1 int32 = 11; a2 = 11;)
const a2 = 1 << 2
预定义常量
const( c0=iota;c1=iota;c2=iota;)//iota 值自动增加const (a = 1 << iota; b ; c;)
枚举
const( day1=iota;day2;day3;day4;)
类型
boolvar b1 bool = true; b2 := (1 == 2);int8,byte int16 int unit unitptr int32 unit32 int64 unit64 int unit整型是不同的,数值运算,比较运算,位运算float32 float64var f1 float32 = 11.1;不能直接比较大小,可以计算减法比较complex64 complex128com1 := 3+12i; 实部real(com1); 虚部imag(com1)stringstr1 := "hi"; len(str1);str1[0];字符串的运算加 x+y长度 len(s)取字符 s[i]字符串的遍历for k,v := range str{fmt.Println(k,v);}rune字符类型byte,uint8的别名,一个是rune 代表unicode字符unicode/utf8包提供utf-8和unicode的转换指针 pointer
数组 array[32]int;[2*N]struct{x,y int32};[3][5]int长度 alen := len(arr)遍历 下标遍历,range遍历,数组是值类型,传递是拷贝切片 slice创建切片 arr[a:b]; make([]int,len,cap);遍历 小标遍历,range遍历常用函数 len长度 cap容量可以基于切片创建切片新增元素 slice=append(slice,11)内容复制 copy(slice1,slice2);字典 map创建字典 make(map[string]int,len)赋值 map1[key] = val1查找字典 p,ok := map1[key1]删除 delete(map1,"k1")通道 chan
结构体 struct
接口 interface
error
流程语句
选择if,else 和else ifif xxx{}else{}switch switch xx{case 1:fallthroughcase 2:default:}select
循环for for{} for a;b;c;{} break 跳出循环continue 继续range 循环跳转HERE:goto HERE
init()函数main前调用
函数
func (t *R) funcname(a type,b type)(ret type, err error){return a,nil
}函数返回nil比较多调用 a:= funcname(a,b); a:= FTT.funcname(a,b); 不定参数 func funcname2(arg ...int){funcname3(arg...)}
任意参数 func funcname3(args ...interface{})匿名函数func(x,y int)int{return x+y}//调用匿名函数func(x,y int)int{print(x,y)}(1,2)
闭包:j :=3;func()(func()){var i int = 1;return fun(){fmt.Printf("i,j:%d,%d\n",i,j);}}()
获取数据的类型
xxx.(type)
nil
代表空
defer和panic 错误处理
error的定义
type error interface{Error() string
}defer 延后处理例如defer func(){}()
panic() 和recover()
panic()释放错误
defer func(){if r:= recover();r!=nil{log.Printf("xxx");}
}()
import
相对路径 import "./xx"
绝对路径 import "xx/xx"
点导入 import . "math" 可以直接 sqrt()
别名 import f fmt 可以f.printf(xxx)
_操作 _"github.com/xxx" 引用包不是直接调用函数,而是使用了包里面的init方法
go的类型系统
基础类型 byte int bool float
符合类型 数组,结构体,指针
任意类型 interface{}
值和引用语义
面向对象
接口go 里面有引用语义的切片,map,channel,接口
结构
type A struct{stat int
}
func ( a A) add(a1 int,b1 int ) int{return a1+b1
}
初始化a1 := new(A)a2 := &A{}a3 := &A{1}a4 := &A{stat:1}自建构造函数func NewA(stat int){return &A{stat}}
匿名组合type B struct{A}type B struct{*A}
可见性通过大小写控制
接口
type Read interface{Reader(buf []byte)(n int,err error)
}
type FileReader struct{int xx;
}
实现接口
func (fr *FileReader)Reader(buf []byte)(n int,err error){return 1,nil
}接口的赋值对象赋值给接口通过引用file_reader := new(FileReader);var b Read = file_reader将接口赋值给接口只需要一个是另外一个的子集即可,反过来不成立IA > IB IA = IB接口查询检查是否实现了接口if xx,ok := file_reader.(Read);ok{}
接口组合type interface1 interface{read()(n int,err error)}type interface2 interface{write()(n int,err error)}type interface3 interface{interface1interface2}
任意类型
interface{}
类型查询
switch v:= v1.(type){case xx1:case xx2:case xx3:
}
并发
通过go实现main方法调用go的方式1 主线程睡眠 2 使用管道等待 3 for或者select死循环管道的声明ch := make(chan int)
管道写入数据ch <- value
管道数据写入变量value := <-chselect go在语言级别支持selectselect{case <-chan1://chan1读取数据执行下面case chan2 <- 1: chan2读取成功default:默认流程}
缓冲机制-自带线程池c :=make(chan int,1023)for i:= range c{printf("receiverd: ",i);}超时机制1 定义一个chan运行,到时间写即可,可以使用select来实现2 也可以 使用 time.After(5.time.Second)传递性可以通过chan传递数据type PipeData struct { value inthandler func(int) intnext chan int}func handle(queue chan *PipeData) { for data := range queue {data.next <- data.handler(data.value)}}单向管道读写 var ch1 chan int写 var ch2 chan<- float32读 var ch2 <-chan int关闭管道close(ch)多核化cpu个数的管道Gosched让出时间片 同步sync.Mutexsync.RWMutex全局唯一操作var once sync.Onceonce.Do(xxx)go并发相关函数:Goexit 退出去Gosched 让出执行权限NumCPU cpu核数量NumGoroutine 执行和排队的携程数GOMAXPROCES 核心数
反射
t := reflect.TypeOf(i) //得到类型的元数据,通过t我们能获取类型定义里面的所有元素
v := reflect.ValueOf(i) //得到实际的值,通过v我们获取存储在里面的值,还可以去改变值
转化为reflect对象之后我们就可以进行一些操作了,也就是将reflect对象转化成相应的值,例如
tag := t.Elem().Field(0).Tag //获取定义在struct里面的标签
name := v.Elem().Field(0).String() //获取存储在第一个字段里面的值
访问mysql数据库
package main
import (_ "github.com/Go-SQL-Driver/MySQL" "database/sql""fmt"//"time"
)
func main() {db, err := sql.Open("mysql", "astaxie:astaxie@/test?charset=utf8") checkErr(err)
//插入数据
stmt, err := db.Prepare("INSERT userinfo SET username=?,departname=?,created=?") checkErr(err)
res, err := stmt.Exec("astaxie", "研发部门", "2012-12-09") checkErr(err)
}
使用redis
package main
import ( "github.com/astaxie/goredis" "fmt"
)
func main() {var client goredis.Client client.Set("a", []byte("hello")) val, _ := client.Get("a") fmt.Println(string(val)) client.Del("a")//list操作var client goredis.Clientvals := []string{"a", "b", "c", "d", "e"} for _, v := range vals {client.Rpush("l", []byte(v)) }dbvals,_ := client.Lrange("l", 0, 4) for i, v := range dbvals {println(i,":",string(v)) }client.Del("l") }
操作xml
package main
import ( "encoding/xml""fmt" "io/ioutil""os"
)
type Recurlyservers struct {XMLName xml.Name `xml:"servers"` Version string `xml:"version,attr"` Svs []server `xml:"server"` Description string `xml:",innerxml"`
}
type server struct {XMLName xml.Name `xml:"server"` ServerName string `xml:"serverName"` ServerIP string `xml:"serverIP"`
}
func main() {file, err := os.Open("servers.xml") // For read access. if err != nil {fmt.Printf("error: %v", err)return }defer file.Close()data, err := ioutil.ReadAll(file) if err != nil {fmt.Printf("error: %v", err) return}v := Recurlyservers{}err = xml.Unmarshal(data, &v) if err != nil {fmt.Printf("error: %v", err)return }fmt.Println(v)
}
正则表达式
func Match(pattern string, b []byte) (matched bool, error error)
func MatchReader(pattern string, r io.RuneReader) (matched bool, error error)
func MatchString(pattern string, s string) (matched bool, error error)
解析正则func Compile(expr string) (*Regexp, error)func CompilePOSIX(expr string) (*Regexp, error) func MustCompile(str string) *Regexpfunc MustCompilePOSIX(str string) *Regexp
查找func (re *Regexp) Find(b []byte) []bytefunc (re *Regexp) FindAll(b []byte, n int) [][]bytefunc (re *Regexp) FindAllIndex(b []byte, n int) [][]intfunc (re *Regexp) FindAllSubmatch(b []byte, n int) [][][]byte func (re *Regexp) FindAllSubmatchIndex(b []byte, n int) [][]int func (re *Regexp) FindIndex(b []byte) (loc []int)func (re *Regexp) FindSubmatch(b []byte) [][]bytefunc (re *Regexp) FindSubmatchIndex(b []byte) []int
模板处理
html/template"
文件处理
目录文件操作的大多数函数都是在os包里面,下面列举了几个目录操作的:func Mkdir(name string, perm FileMode) error
创建名称为name的目录,权限设置是perm,例如0777func MkdirAll(path string, perm FileMode) error
根据path创建多级子目录,例如astaxie/test1/test2。func Remove(name string) error
删除名称为name的目录,当目录下有文件或者其他目录是会出错func RemoveAll(path string) error
根据path删除多级子目录,如果path是单个名称,那么该目录不删除。文件func Create(name string) (file *File, err Error)根据提供的文件名创建新的文件,返回一个文件对象,默认权限是0666的文件,返回的文件对象是可读写func NewFile(fd uintptr, name string) *File根据文件描述符创建相应的文件,返回一个文件对象
打开func Open(name string) (file *File, err Error)该方法打开一个名称为name的文件,但是是只读方式,内部实现其实调用了OpenFile。func OpenFile(name string, flag int, perm uint32) (file *File, err Error)名字,方式,权限写func (file *File) Write(b []byte) (n int, err Error)写入byte类型的信息到文件
func (file *File) WriteAt(b []byte, off int64) (n int, err Error)在指定位置开始写入byte类型的信息
func (file *File) WriteString(s string) (ret int, err Error)写入string信息到文件读func (file *File) Read(b []byte) (n int, err Error)func (file *File) ReadAt(b []byte, off int64) (n int, err Error)
字符串处理
字符串操作
func Contains(s, substr string) bool
func Join(a []string, sep string) string
func Index(s, sep string) int
func Replace(s, old, new string, n int) string
func Repeat(s string, count int) string
func Split(s, sep string) []string
func Trim(s string, cutset string) string
func Fields(s string) []string字符串转换str := make([]byte, 0, 100)str = strconv.AppendInt(str, 4567, 10) str = strconv.AppendBool(str, false)str = strconv.AppendQuote(str, "abcdefg")str = strconv.AppendQuoteRune(str, '单')a := strconv.FormatBool(false)b := strconv.FormatFloat(123.23, 'g', 12, 64) c := strconv.FormatInt(1234, 10)d := strconv.FormatUint(12345, 10)e := strconv.Itoa(1023)a, err := strconv.ParseBool("false") if err != nil {fmt.Println(err) }b, err := strconv.ParseFloat("123.23", 64) if err != nil {fmt.Println(err) }c, err := strconv.ParseInt("1234", 10, 64) if err != nil {fmt.Println(err) }d, err := strconv.ParseUint("12345", 10, 64) if err != nil {fmt.Println(err) }e, err := strconv.Itoa("1023") if err != nil {fmt.Println(err) }fmt.Println(a, b, c, d, e) }
websocket
"code.google.com/p/go.net/websocket" 服务
gdb调试
日志系统
seelog
部署
daemon
性能监控
net/http/pprof
runtime/pprof
常用的库
net包
socket 库Dial(net,addr string)(Conn,error)conn,err := net.Dial("tcp","127.0.0.1:8888")conn,err := net.Dial("udp","127.0.0.1:8888")conn,err := net.Dial("ip4:icmp","www.baidu.com")conn,err := net.Dial("ip4:1","10.113.1.103")目前支持的协议:tcp tcp4 tcp6 udp upd4 udp6 ip ip4 ip6
dial实际上是对函数的封装func DialTCP(net string, laddr, raddr *TCPAddr) (c *TCPConn, err error) func DialUDP(net string, laddr, raddr *UDPAddr) (c *UDPConn, err error) func DialIP(netProto string, laddr, raddr *IPAddr) (*IPConn, error)
func DialUnix(net string, laddr, raddr *UnixAddr) (c *UnixConn, err error)http库,net/http包func (c *Client) Get(url string) (r *Response, err error)func (c *Client) Post(url string, bodyType string, body io.Reader) (r *Response, err error)
func (c *Client) PostForm(url string, data url.Values) (r *Response, err error)
func (c *Client) Head(url string) (r *Response, err error)
func (c *Client) Do(req *Request) (resp *Response, err error)http服务端编程http.Handle("/foo", fooHandler)http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) {fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))})log.Fatal(http.ListenAndServe(":8080", nil))或者是s := &http.Server{Addr:":8080",Handler:myHandler,ReadTimeout:10 * time.Second,ReadTimeout:10 * time.Second,MaxHeaderBytes: 1 << 20,}log.Fatal(s.ListenAndServe())https有点不同log.Fatal(http.ListenAndServeTLS(":10443", "cert.pem", "key.pem", nil))RPCnet/rpc直接支持服务端arith := new(Arith) rpc.Register(arith) rpc.HandleHTTP()l, e := net.Listen("tcp", ":1234") if e != nil {log.Fatal("listen error:", e)}go http.Serve(l, nil)客户端client, err := rpc.DialHTTP("tcp", serverAddress + ":1234") if err != nil {log.Fatal("dialing:", err)}args := &server.Args{7,8}var reply interr = client.Call("Arith.Multiply", args, &reply) if err != nil {log.Fatal("arith error:", err)}fmt.Printf("Arith: %d*%d=%d", args.A, args.B, reply)GobGob 是 Go 的一个序列化数据结构的编码解码工具json处理压缩一个数据,放到另外一个数据里面func Marshal(v interface{}) ([]byte, error)func Unmarshal(data []byte, v interface{}) error
golang的基本语法相关推荐
- go linux 开发工具,golang的基础语法和常用开发工具详解
golang的基础语法 golang的基础语法和其他语言大部分都差别不大,如果我们有学习过其他语言,比如JavaScript,php,java,python等,有其他语言的语法基础,那么我们学习gol ...
- Golang的基本语法学习笔记
1.var 变量名称 类型 变量声明后没有初始化的话 值为空 变量首字符不能为数字 关键字不能作为变量名 同一个作用域不允许变量重复声明 但是以下属于赋值,是允许的 一次定义多个变量 注意:赋值时必须 ...
- GoLang笔记—基础语法篇
GoLang笔记 Go(又称 Golang)是 Google 的 Robert Griesemer,Rob Pike 及 Ken Thompson 开发的一种静态类型.编译型语言.Go 语言语法与 C ...
- golang select default continue_golang系列——基础语法
golang系列的文章包含多篇文章,总篇如下,其中包含各篇文章的指引 明月映江雪:golang系列--个人学习笔记总篇zhuanlan.zhihu.com golang的基础语法和其他语言有共通之处 ...
- Golang入门(2):一天学完GO的基本语法
摘要 在配置好环境之后,要研究的就是这个语言的语法了.在这篇文章中,作者希望可以简单的介绍一下Golang的各种语法,并与C和Java作一些简单的对比以加深记忆.因为这篇文章只是入门Golang的第二 ...
- Golang正则笔记 :使用正则表达式处理题库文本
前言 由于企业内部的一些考试需要,有些同事要时常通过一个word格式的题库文件来查询相应题目,但在手机上用word进行查询,总觉得操作上很不方便.借着这个契机,应用Golang和Kotlin开发了一个 ...
- golang 运算与循环
一.golang运算符 1.算术运算符 + 相加 - 相减 * 相乘 / 相除 % 求余 ++ 自增 -- 自减 2.关系运算符 == 等于 != 不等于 > 大于 < 小于 >= ...
- 使用Golang搭建gRPC服务提供给.NetCore客户端调用
gRPC概述 RPC 说到gRPC就不得不提RPC,所谓RPC(remote procedure call 远程过程调用)框架实际是提供了一套机制,使得应用程序之间可以进行通信,简单点来说就是我A机器 ...
- golang 导入自定义包_goLang引入自定义包的方法
看完golang的基本语法后,为了模块化编程,试用了下golang的包管理,结果真踩了几个坑,总结一下吧. 一. 设置$GOPATH环境变量 golang和C或php不一样,不会自动查找当前路径下的文 ...
最新文章
- opencv随机数的产生
- I-string_2019牛客暑期多校训练营(第四场)
- 二叉树的遍历(递归,非递归,Morris)
- Python:self理解
- macOS Big Sur正式版发布!Big Sur安装失败?更新时卡住了怎么办?
- sin18度用计算机怎么算,sin18度等于多少怎么计算?谢谢
- 高性能 Go 日志库 zap 设计与实现
- 在一个windows服务下,安装多个mysql服务。
- 自定义Toast的出现样式
- 量子计算与PKS信创体系首次融合,实现算力跨越
- 整理了上千个 Python 工具库,涵盖24个大方向
- ubuntu18安装详细教程
- 我国古代的度量衡和音律的关系
- 如何通过供应链管理来居家做菜?
- gets与puts的使用,Str系列字符串的使用
- 08:go语言数字类型
- C/C++的左值和右值
- 使用tcpdump探测TCP/IP三次握手
- Linux重定向管道——双通、三通管道一篇学会【CenOs】
- 利用ArcGIS处理土地利用数据:计算fishnet每个格网中不同地类的面积