• 语言特性


    类型

    值类型:int bool string float struct

    引用类型:slice map chan 指针  interface

    值类型和引用类型都是一次将原有内容拷贝过去的副本,值类型是整个内存拷贝过去(1kb的内容就产生1kb的副本),引用类型是将内存的地址拷贝过去。

    像int,要引用传递就要使用*int

    像chan,slice,本身就是引用传递,不需要加*

    // 交换ab的值
    package main
    
    import "fmt"
    
    // 把ab的地址给函数,ab的地址发生了内存拷贝
    // 然后这个地址指向的内存空间的内容被改变了
    // 所以ab的值变了
    func swap(a,b *int) {
    	t := *a // 把a的地址给t
    	*a = *b // b的地址给a
    	*b = t
    }
    
    func main() {
    	a,b := 1,2
    	swap(&a, &b)
    	fmt.Println(a,b)
    }
    

      

    // 这样就是把ab的地址传递进来,然后不是去改变地址指向的内容
    // 而是在改地址这个值,这是内存拷贝,ab内容不会变
    func swap(a,b *int) {
    	t := a
    	a = b
    	b = t
    }
    
    func main() {
    	a,b := 1,2
    	swap(&a, &b)
    	fmt.Println(a,b)
    }
    

      

    变量作用域

    在函数内部的变量,生命周期只有在这个函数里面

    在包里面的变量,如果是首字母小写,只能包能访问。如果首字母大写,可以在整个程序中访问

    // 在全局变量中
    // 申明a为100
    // 申明b,同时执行b = 100 的代码,这是不行的。
    // 全局变量只能声明,不能执行代码块
    var a int = 100
    var b int
    b = 100
    

      

    数据类型

    int,int8,int16, int32, int64

    int8 的范围是-127 -- 127

    float32 四个字节, float64 8个字节  没有float。

    // 即使同样是整型,int8 和int16之间也要类型转换
    // 字符串里要加“”,就用``,它表示里面的内容不会转义,比如
    ,比如换行
    func test() {
    	var a int8 = 10
    	var b int16 = int16(a)
    	var s string = `
    		my name is "jabbok"
    		i am a christian
    	`
    	fmt.Println(b)
    	fmt.Println(s)
    }
    

      

    天然并发goroute

    轻量级线程,比物理线程轻,可以同时开上万个。

    每个goroute是独立的调度单位。一个goroute无法访问另一个goroute内存中的变量。

    c++里用的是物理线程,如果同时开上万个机器就挂了。

    使用go命令,就会并发调用add函数。100个add函数会同时执行。

    如果没有time.Sleep(time.Second*2)这条语句,子线程还没执行完,主线程就已经退出,子线程会来不及执行。

    package main
    
    import (
    	"fmt"
    	"time"
    )
    
    func add(a,b int) {
    	sum := a^b * a^b
    	fmt.Println(sum)
    }
    
    func main(){
    	for i := 0; i < 100; i++ {
    		go add(i, i)
    	}
    	time.Sleep(time.Second*2)
    }
    

      

    channel

    在linux中由pipe的概念。原来两个进程之间是无法数据通信的,管道可以让b进程读取a进程的数据。

    channel的作用是goroute之间数据通信

    // 创建一个管道,make分配一个内存空间,定义一个int类型的chan,容量是3
    // 把几个int值放进管道,放2个,len就是2.如果放4个,最新的数据不会丢,但会阻塞,就会报错:
    // fatal error: all goroutines are asleep - deadlock!
    // 从管道取数据是先进先出,取出后,len减少。
    func test_chan(){
    	pipe := make(chan int, 3)
    	pipe <- 1
    	pipe <- 2
    	pipe <- 3
    	fmt.Println(len(pipe))
    
    	t1 := <- pipe
    	fmt.Println(t1)
    	fmt.Println(len(pipe))
    }
    

      

    goroute之间通过pipe数据通信

    // 申明一个pipe,然后传参到add
    // 在main里调用100个add线程,把结果放到pipe
    // 从pipe取值到value时,因为pipe还没有数据集,所以会阻塞
    // 主线程不会提前退出,会从pipe里取到100个元素后才会退出。
    var pipe chan int
    
    func add(a ,b int, pipe chan int) {
    	pipe <- (a + b)
    }
    
    func main() {
    	pipe := make(chan int,100)
    	for i:=0; i < 100; i++ {
    		go add(i,i,pipe)
    	}
    
    	for i:=0; i < 100; i++ {
    		value := <- pipe
    		fmt.Println(value)
    	}
    }
    

      

    多返回值

    在python里要返回多个数据,基本是用list或者dict,go里可以直接返回多个返回值

    func add(a ,b int) (int,int){
    	sum := a + b
    	avg := sum/2
    	return sum,avg
    }
    
    func main() {
    	sum,avg := add(1,2)
    	fmt.Printf("sum=%d,avg=%d",sum,avg)
    }
    

      

    // 对于一个有多个返回值的func,如果我只需要一个返回值,其他的用_代替
    func main() {
    	sum,_ := add(1,2)
    	fmt.Printf("sum=%d",sum)
    }
    

      

    包管理package

    在 package main里,,必须有且只有一个main函数。这是入口函数,package main是用于生成可执行文件的。

    在go里,package和文件夹对应,比如一个user相关的包就是一个user的文件夹 

    内存管理new&make

    new用于给值类型分配内存,make给引用类型分配内存

    // new返回地址,所以i是个地址
    // *i是具体的内容
    // 因为i是地址,所以赋值要用*i
    func new_exc() {
    	i := new(int)
    	fmt.Println(i)
    	fmt.Println(*i)
    	*i = 100
    	fmt.Println(*i)
    }
    

      

    错误处理

    day4 内置函数,暂时不想看了

     

    项目目录结构

    project

      /src/代码文件

        app/main/main.go入口文件

        app/calc/xx.go功能函数等

      /bin/可执行文件

      /vender/第三方包

      /pkg/依赖的静态库

    export GOPATH = project目录

    导入import

    函数名首字母必须大写

    导入其他package时以src为根目录,比如导入src/go_test/calc这个目录,就是import "go_exc/calc"

    编译

    go run是类似运行一个python脚本

    go build是组织目录结构,编译带main package的包生成一个可执行文件,编译其他package生成lib库

    go编译只生成一个文件,不会有各种依赖库问题,在本地编译好了,放到线上直接就能跑,不依赖任何环境。

    gofmt是代码格式化命令,-w参数表示写入源文件

    # go run时,在同一个包下的calc里的func,只要引入main,就会自动被main找到,但要在run时加上去
    D:codegogotestsrcgo_exc>go run main.go calc.go
    

      

    D:codegogotest>go build go_exc/main
    
    #在项目目录下执行go bulid编译
    #go_exc是src下的一个目录,里面有一个main入口函数
    #go build后面不需要加src,它会自动去src下找这个目录
    #编译完成后在项目目录生成exe文件
    

      

    D:codegogotest>go build -o bin/main go_exc/main
    #指定生成目录和文件名
    

      

      

  • 相关阅读:
    转:CRF++
    ProBase
    图形数据库 Neo4j 开发实战
    Linux 下升级python和安装pip
    TensorFlow (RNN)深度学习 双向LSTM(BiLSTM)+CRF 实现 sequence labeling 序列标注问题 源码下载
    开源项目kcws代码分析--基于深度学习的分词技术
    文本情感分类(二):深度学习模型
    文本情感分类(一):传统模型
    重要博文
    LSTM 文本情感分析/序列分类 Keras
  • 原文地址:https://www.cnblogs.com/jabbok/p/11299079.html
Copyright © 2020-2023  润新知