加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

golang的基本语法

发布时间:2020-12-16 18:18:12 所属栏目:大数据 来源:网络整理
导读:最近又打算玩玩golang,打算把工作中的爬虫从脚本语言迁移到golang,读了两本golang的书,对立面的语法做了一个简单的整理。 编程语言的选择 0 业务的要求1 性能2 表达能力3 是否容易上手4 坑和维护 变量 变量的声明var xx type 或者 var (xx type xxx type)

最近又打算玩玩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;)

类型

bool
    var b1 bool = true;  b2 := (1 == 2);

int8,byte int16 int unit unitptr int32 unit32 int64 unit64 int unit
    整型是不同的,数值运算,比较运算,位运算


float32 float64
    var f1 float32 = 11.1;
    不能直接比较大小,可以计算减法比较

complex64 complex128

    com1 := 3+12i;  实部real(com1); 虚部imag(com1)

string
    str1 := "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 if
        if xxx{
        }else{
        }

    switch 
        switch xx{
            case 1:
                fallthrough
            case 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,%dn",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{
        interface1
        interface2
    }

任意类型

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 := <-ch

select 
    go在语言级别支持select
    select{
        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 int
            handler func(int) int
            next 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.Mutex
    sync.RWMutex
    全局唯一操作
        var once sync.Once
        once.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.Client
    vals := []string{"a","b","c","d","e"} 
    for _,v := range vals {
        client.Rpush("l",[]byte(v)) 
    }
    dbvals,_ := client.Lrange("l",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) *Regexp
    func MustCompilePOSIX(str string) *Regexp
查找
    func (re *Regexp) Find(b []byte) []byte
    func (re *Regexp) FindAll(b []byte,n int) [][]byte
    func (re *Regexp) FindAllIndex(b []byte,n int) [][]int
    func (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) [][]byte
    func (re *Regexp) FindSubmatchIndex(b []byte) []int

模板处理

html/template"

文件处理

目录

文件操作的大多数函数都是在os包里面,下面列举了几个目录操作的:
    func Mkdir(name string,perm FileMode) error
创建名称为name的目录,权限设置是perm,例如0777
    func 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,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,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",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",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,raddr *UDPAddr) (c *UDPConn,err error) 
    func DialIP(netProto string,raddr *IPAddr) (*IPConn,error)
func DialUnix(net string,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,MaxHeaderBytes: 1 << 20,}
            log.Fatal(s.ListenAndServe())

    https有点不同
        log.Fatal(http.ListenAndServeTLS(":10443","cert.pem","key.pem",nil))


    RPC
        net/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 int
            err = 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)

    Gob
        Gob 是 Go 的一个序列化数据结构的编码解码工具


    json处理

        压缩一个数据,放到另外一个数据里面
        func Marshal(v interface{}) ([]byte,error)
        func Unmarshal(data []byte,v interface{}) error

        ?? JSON中的布??值将会??换为Go中的bool类型; ?? 
        数值会被??换为Go中的float64类型;
        字符????换后还是string类型;
        JSON数组会??换为[]interface{}类型;
        JSON对象会??换为map[string]interface{}类型; ?? 
        null值会??换为nil。


    md5和sha1
        package main 
        import(
        "fmt"
        "crypto/sha1"
        "crypto/md5"
        )

    Md5Inst:=md5.New()
    Md5Inst.Write([]byte(TestString))
    Result:=Md5Inst.Sum([]byte(""))
    fmt.Printf("%xnn",Result)
    Sha1Inst:=sha1.New()
     Sha1Inst.Write([]byte(TestString))
     Result=Sha1Inst.Sum([]byte(""))
     fmt.Printf("%xnn",Result)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读