文章目录
1.1 变量定义
1.1.1 定义类型
go定义变量的类型跟之前的c++是不一样的,go的类型是定义在后面的:
func init1() {
var a int = 11
var s string = "123"
fmt.Println(a, s)
}
其实go定义局部变量是自动赋了初值的,不用像c++那样需要手动赋初值,但是既然c++养成了习惯,就在go这边一直沿用也是没什么问题的。
1.1.2 自动推导类型
既然是新型语言,那变量的推导是少不了的,现在连c++都有auto了,go支持一个推导不过分吧。
func init2() {
var a , b = 11, 12
var s = "234"
fmt.Println(a, b, s)
}
如果是自动推导,可以写成一行:
func init3() {
var a , b, s = 11, 12, "234"
fmt.Println(a, b, s)
}
go为了简介,还另外有一个简单的写法:
func init4() {
a , b, s := 11, 5677, "789"
fmt.Println(a, b, s)
}
这种 := 好像是有在一门语言中用到,用了这个就可以不用写var,也能自动推导出变量类型。
1.1.3 包内变量
上面介绍了局部变量,接下来看看包内变量,其实就是一个包内有效的。
var aa = 333
var ss = "32442"
// ee := "rfg" 包内变量不能这样定义 需要var开头
包内变量,只能用var开头,不能使用:=号了。
还有一个简写的方法:
var (
aaa = 444
sss = "32455"
)
简写的方法,就是把var统一起来,用一个括号包含,里面就可以定义变量了。
1.2 内建变量类型
学习一门编程语言,还是从内建变量类型开始
-
bool, string
-
(u)int, (u)int8, (u)int16, (u)int32, (u)int64, uintptr
-
byte, rune
-
float32, float64, complex64, complex128
其中整数类型,前面有u,说明是无符号类型,没有就是有符号类型,int,类型是根据系统位数决定的长度,uint也是。最后一个uintptr是无符号整形,用于存放一个指针。
rune其实是char,不过由于各国的字符编码的问题,char只能表示8位,所以go这里使用了rune,rune是32位的,相当于int32,这样Unicode变量也可以存的下
complex64,complex128 这两个是复数类型,这真实好多年不搞数学了,都忘关了。
complex64是有32位实数,和32位虚数,分别是用float32存储的,同理complex128就是float64存储了。
go的复数定义:
var fu complex64 = 9 + 9i
使用i,这样跟我们学的数学是一样的。
最后一个是强制类型转换,go是强类型语言,如果需要类型转换,是需要显示类型转换的:
func init1() {
var a int = 11
var s string = "123"
var fu complex64 = 9 + 9i
var c float32 = float32(a) // 强制类型转换
fmt.Println(a, s, fu, c)
}
1.3 常量
go语言也是支持常量的,也支持定义类型,和不定义类型:
const (
filename = "234.txt" // 也是可以用const声明
)
func const1() {
const filename string = "234.txt" // 可以定义类型
const a, b int = 3, 4
fmt.Println(a, b, filename)
}
func const2() {
const filename = "234.txt" // 也可以不定义
const a, b = 3, 4 // 如果是数值的,不定义类型,
// 是可以作为数值类型使用,可以用作float也可以用作int
fmt.Println(a, b, filename)
}
1.4 枚举
go语言并没有枚举类型,go只是使用了const来定义枚举:
const (
CPP = 0
JAVA = 1
JS = 2
GO = 3
)
这样写是不是很傻,会不会有其他语言一样,可以只写一个,后面就自增了呢?
const ( // 错误的写法
CPP = 0
JAVA
JS
GO
)
我尝试了一下按c++这种,只定义第一个,然后没有定义,发现这样是错的,记住了这样是错误的。
那正确的应该是这样写:
const (
CPP = iota
JAVA
JS
GO
)
这种才是正确的,iota,就是自增意思。
其实我们也可以用iota玩一个高级玩法:
const (
b = 1 << (10 * iota)
kb
mb
gb
tb
pb
)
用这种表达式的方面,来把这种有规律的式子才表示出来。
1.5 条件语句
1.5.1 if
go的if判断的条件是不需要括号的:
func if1 (socre int) string {
g := ""
if socre < 60 {
g = "F"
} else if socre < 70 {
g = "B"
}
return g
}
这种就是常规操作,其实go还可以这么操作:
func if1 (socre int) (string, error) {
g := ""
var err error
if socre < 60 {
g = "F"
} else if socre < 70 {
g = "B"
} else {
err = errors.New("0 is not supported")
}
return g, err
}
func main() {
if g, err := if1(80); err != nil { // 是可以把函数的返回值,直接在if中做判断
fmt.Println("cuowu ")
} else {
fmt.Printf("g = %s ", g)
}
return ;
}
好像c语言是不是也可以这么写,有点小影响。
1.5.2 switch
go使用switch是不需要写break语句的,go语言会自己break,不用操心这个:
func if2 (socre int) (string) {
g := ""
switch socre {
case 60:
g = "F"
case 50:
g = "F-"
default:
panic("cuowu")
}
return g
}
这是正规操作,其实go还可以支持这样:
func if3 (socre int) (string) {
g := ""
switch {
case socre < 60:
g = "F"
case socre < 70:
g = "B"
default:
panic("cuowu")
}
return g
}
go还真是偷懒者天堂啊,语法能省就省啊。
1.6 循环语句
go的循环语句只有for,没有while,只要for就能把while的工作做了:
func for1() {
for i:= 0; i<100; i++ {
fmt.Println("i = %d", i)
}
}
比较常规的操作,for可以适当的减少条件或者后面执行的代码,这在c++中也支持,for可以直接写出一直循环的代码不:
for {
fmt.Printf("1")
}
只要这样写就可以了,不用带参数,for就会一直循环下去。
1.7 函数
go函数我们之前也写过了,就是类型在后面,看习惯了也正常了。
func func1(a,b int) int {
return a+b
}
是不是比较简单,难道go函数真的这么简单么。
1.7.1 多个返回值
其实go函数是可以多个返回值的:
func func2(a,b int, op string) (int, error) {
switch {
case op == "+":
return a+b, nil
case op == "-":
return a-b, nil
default:
return 0, fmt.Errorf("cuowu")
}
}
这样就是返回了两个值,一般go的两个返回值一个是值,另一个是错误码,这也就是我们在c++中写代码就不能返回一个错误码,所以go应该是改进了这一点。
1.7.2 返回值可以定义变量
go的返回值可以定义变量,这个变量是真个函数有用,就相当于我们在前面定义了两个返回值变量:
func func3(a,b int, op string) (value int, err error) {
switch {
case op == "+":
value =a+b
case op == "-":
value = a-b
default:
err = fmt.Errorf("cuowu")
}
return
}
有点像c++的引用,这样return就不用带参数,但是这样就有点问题,如果函数过长,可能就不知道这个返回值在哪赋值的
1.7.3 可以忽略返回值
如果我们只使用了第一个返回值,而第二个返回值不需要,但是这个函数确有两个,go语法比较严格,定义了变量就一定要使用,这种情况只能使用忽略:
value, _ := func3(1,2, "*")
fmt.Println(value)
这样就忽略了返回值
1.7.4 函数作为参数
go的函数也支持函数作为函数参数,是不是说的跟绕口令一样。
func func4(op func(int,int) int, a,b int) int {
return op(a, b)
}
这个就是所谓的回调函数,在c++中也是存在的。
1.7.5 支持匿名函数
go也支持匿名函数:
func4(func (a,b int) int {
return a+b
}, 1, 2)
里面的就是一个匿名函数。
go不支持lamda,不支持默认参数,也不支持重装,语法比较简单。
1.7.6 可变参数
func func5(numbers ... int) int {
res := 0
for i:= range numbers {
res += numbers[i]
}
return res
}
可变参数用的地方还不少
1.8 指针
go的指针不能运算,这也太简单了。。。。。。
a := 1
var pa *int = &a
fmt.Println(pa)
用法跟c差不多,就是不能运算,函数参数用指针,就是相当与传地址,go没有引用。
1.9 总结
这一篇把go的基础语法学习了一遍,跟其他语言是有点差别,不过也不算大。