准备深飘的第一天:Go语言
Go语言中没有项目的说法,都是说包。
GoRoot:Go语言的安装目录 我的 E:/tool/go
GoPath:Go语言的工作目录
问题1:
warning: GOPATH set to GOROOT (E:\Tools\go) has no effect go run: cannot run non-main package
解决方案:
建一个main包,程序入口放在main包下。
写完Helloworld,接着看语法结果。
基础语法:和java差不多,但是java每句都需要使用;隔开,但是在实际开发过程中go不推荐使用,因为这些已经由编译器自动完成了。
关键词:
break |
default |
func |
interface |
select |
case |
defer |
go |
map |
struct |
chan |
else |
goto |
package |
switch |
const |
fallthrough |
if |
range |
type |
continue |
for |
import |
return |
var |
Func、const、var、type 感觉在前端ES6中有点眼熟;
Struct在solidity中用来定义对象,结构体;
Select、range在sql中见过
Goto在C中,
Chan、defer、fallthrough就是真的不得而知了。
查了一下
Fallthrough 用与go的switch case中,因为case后面是自带break的,意思就是如果case条件满足,就自动跳出了,但是可以用fallthrough强制执行下一条,也不会去判断下一个case 的条件是否满足,举例:
输出:
挺好用的。
Chan 这个就不是一句话能解释清楚的东西了,看了官方文档上的解释,我的认知是,第一个go语言由一个叫通道的概念,目的是为了资源的合理分配,让程序运行的时候都排起队来。 第二个上代码。
定义通道:
写完开开心心的运行,结果心塞了。
Deadlock!!!死锁!!这让咋整呀,出师未捷身先死呀。
接着看文档咯。
果不其然,看完之后有点懵的,这为啥要搞的那么复杂呀,不是说简单、轻便么?突然觉得还是java香。。。没办法,硬着头皮搞吧!
通道接受特性:
- 收发在两个不同的goruntine中,之前说是排队,然后名字又叫通道,我觉得应该是就是它把现在堵住了,又没有其它的goruntine接收,就锁上了。
- 上速后半部分的意思
- 通道每次接受一个元素,,,这个就过分了。
反正看着代码撸出来了一个可以正常输出的东西
代码结构大概清楚了一点,但是至于为什么要这样操作。
好像跳的有点快了,继续回来看。接着就是学习数据类型。
1.布尔型
布尔型的值只可以是常量 true 或者 false。一个简单的例子:var b bool = true。
2.数字类型
整型 int 和浮点型 float,Go 语言支持整型和浮点型数字,并且原生支持复数,其中位的运算采用补码。
Int 、Uint8、uintptr uint(正整型)
3.字符串类型:
字符串就是一串固定长度的字符连接起来的字符序列。Go的字符串是由单个字节连接起来的。Go语言的字符串的字节使用UTF-8编码标识Unicode文本。
4.派生类型:
包括:
(a) 指针类型(Pointer)
(b) 数组类型
(c) 结构化类型(struct)
(d) 联合体类型 (union)
(e) 函数类型
(f) 切片类型
(g) 接口类型(interface)
(h) Map 类型
(i) Channel 类型
可以分为值类型和引用类型
New 和 make 的区别;
- new不太常用,使用new返回的是该指针的默认初始值。比如:
Var i int ; i = new(int); i的值为0
但是值类型的数据定义了之后只是一个指针地址,并没有分配内存,必须要初始化之后才会分配内存空间。
- Make 只能用于slice,map以及chan的内存创建 他的返回值就是这个类型本身的
func make(t Type, size ...IntegerType) Type
总结:
1.二者都是用来做内存分配的。
2.make只用于slice、map以及channel的初始化,返回的还是这三个引用类型本身;
3.而new用于类型的内存分配,并且内存对应的值为类型零值,返回的是指向类型的指针。
指针类型、联合体类型、切片类型、Channel类型
指针类型 引用类型数据的地址
输出:
联合体类型、结构化类型:
联合体类型变量的所有成员变量共享一个内存空间,但是变量可以有多个,每次赋值旧值会被新值给冲去。
结构化类型变量的各个成员变量有自己的内存空间,互不干预,长度等于成员变量长度之和。
申明变量的方式和solidity语言是一致的
方式一
Var a uint8
a = 10
方式二
Var a = 10
方式三
a := 10
多变量申明的时候要注意,
方式一
var a,b uint
a = 10
b = 5
方式二
Var a,b = 10
方式三
a , b := 10
注意:
//类型不同多个变量, 全局变量, 局部变量不能使用这种方式
var (
vname1 v_type1
vname2 v_type2
)
//这种不带声明格式的只能在函数体中出现
//a, b := 123, "hello"
函数内的变量申明了之后如果不能被使用也会报错的。a declared but not used
可以存在多变量同行赋值不同值的情况
a , b , c := 1,”a”,[1]
因此交换两个变量的值可以直接使用 a,b = b,a
学完变量再来看常量 const
常量只可以有布尔、数字、字符串
Iota 特殊常量
在每一个const关键字出现时,被重置为0,然后再下一个const出现之前,每出现一次iota,其所代表的数字会自动增加1;
const (
i=1<<iota
j=3<<iota
k
l )
fmt.Println("i=",i)
fmt.Println("j=",j)
fmt.Println("k=",k)
fmt.Println("l=",l)
输出结果是
i= 1
j= 6
k= 12
l= 24
这里的k,l的值有点让你不得而知,猜测应该是3<<2,3<<3
其中有点左移和右移的概念,有点遗忘了。看了一下 左移 就是乘以 2的n次方 ,右移就是除以2的n次方
运算符的学习
运算符和java的一致的,就是有两个特殊的&,*。&表示返回变量存储的地址,*表示地址变量。
条件语句
有个新的select语句,他用法和switch是一致的,但是他是选择其中一个符合条件的case执行,如果没有一个符合就堵塞,有default就直接执行default中的语句,如果有多个就会执行其中随意的一个。它会把所有的case都计算一遍。
循环语句
Goto:当执行到有共同标识的地方,会跳到有goto标识的地方继续执行。
函数定义
func function_name( [parameter list] ) [return_types]
{
函数体
}
注:1.返回类型如果没有,[return_type]非必须
- 可以有多个返回值
默认go参数传递使用的是值传递。
函数作为值:定义的函数可以当成一个值使用
闭包:匿名函数,可在动态编程中使用
方法:包含了接受者的函数
函数中的变量作用范围:
注:全局变量可以和局部变量同名,但是局部变量有先级别要高于全局变量。
数组变量
定义:var balance = []float32{1000.0, 2.0, 3.4, 7.0, 50.0}
指针变量
定义:
I := 5
var ptr = *int
ptr = &I
fmt.Printf(*ptr)
可以通过*指针变量,根据变量得到值
Go在输出的时候:
fmt.Printf("type of c:%T\n", c) 输出c的type
fmt.Printf("value of c:%v\n", c) 输出c的value
指针数组
指针的指针 定义时加 **,访问的时候也要加 **
指针做形式参数,和普通数据类型是一样的。
结构体变量 struct
和java的对象概念有点相同,
注意:如果在做形参的时候,可以传递地址指针,在使用实参的时候,可以直接得到内容。
切片变量slice
定义:slice1 := make([]type, len)
初始化:s :=[] int {1,2,3 }
可以用数组:s := arr[startIndex:endIndex]或者只用一个参数的
len() 和 cap() 函数
append() 和 copy() 函数
输出:
常规slice , data[6:8],从第6位到第8位(返回6, 7),长度len为2, 最大可扩充长度cap为4(6-9)
另一种写法: data[:6:8] 每个数字前都有个冒号, slice内容为data从0到第6位,长度len为6,最大扩充项cap设置为8
数组和切片最大的区别是,赋值的时候,数组是值传递,切片是地址传递
Range 用来求集合、数组、切片、map的范围变量,就是用于遍历的
写法:
For index,item := range slice/map
map集合
递归 斐波拉契数列
Feibo(i int) int{
If(i<2){
Return i
}
Return Feibo(i-2)+Feibo(i-1)
}
Var i int
For i=0;i<10;i++{
Fmt.Println(Feibo(i))
}
go语言类型转换
强转类型(变量)
Var i int32
Float32(i)
go语言接口
跟java的接口有点相似,就是java的是类实现接口,在类的结构体里面重写接口中的方法,但是go语言是方法的传参用不同的接口,在新建对象的时候传的参数也是接口,从而实现的接口。