Go 开发基础入门——2
请关注我的个人博客
数据类型转换
通过类型前置加一个圆括号 T(表达式) T表示要转化的类型,表达式包括:变量,数值,函数返回值等 int(8.2) int(80.5) 布尔型无法与其他类型转换
int转换为string OK
string转换为int NO
eg:
chinese := 90
english := 90.9
result := string(chinese)
fmt.Println(chinese,english,result)
90 90.9 Z
```
常量
常量是一个简单值的标识符,在程序运行时,不会被修改的量。
常量中的数据类型只可以是布尔型、数字型(整数型、浮点型和复数)和字符串型。
常量的定义格式:
const identifier [type] = value
你可以省略类型说明符 [type],因为编译器可以根据变量的值来推断其类型。
显式类型定义: const b string = "abc"
隐式类型定义: const b = "abc"
多个相同类型的声明可以简写为:
const c_name1, c_name2 = value1, value2
常量用于枚举(常量组):
也可以使用 const()定义块,定义多个,每个常量单独一行,例如
const (
c6 = 42
c7 = 1000
)
const()块定义时,如果常量未给出定义,则延续上面的定义规则,例如:
const (
c7 = 42
c8 // c8 = 42
c9 // c9 = 42
)
iota迭代定义常量:
const配合iota关键字使用,可以定义一组由0开始+1迭代的常量 演示语法:
const (
gender_secret = iota
gender_male // = iota
gender_female // = iota
)
此时,三个常量值,分别是,0, 1, 2 iota的规则是:若iota出现在const()中,那么const()定义的第一行的iota就是0,第二行就是0+1=1,不论iota是否被常量使用。演示如下:
const (
c1 = 42 // iota = 0,虽然未使用iota,但后边(const()中)有使用,此时iota被初始化为0,下面每行累加1
c2 = iota // iota = 1,iota继续累加,使用了iota
c3 = 1024 // iota = 2,同样未使用,但iota的值继续累加。c3 被定义为1024
c4 // iota = 3,c4延续上面的定义c4=1024,iota继续累加
c5 = iota // iota = 4,iota继续累加,使用了iota
c6 = iota // iota = 5,iota继续累加,使用了iota
)
此时结果为:42, 1, 1024, 1024, 4, 5
函数
func 和 JavaScript中定义类似 定义之后在main中来调用,流程很好理解
-
Go中函数为一等公民:
- 函数本身可以作为值来传递
- 支持匿名函数和闭包
- 函数可以满足接口
-
如何声明函数(函数定义)
func 函数名 (参数列表) (返回值参数列表){ //函数体 } 参数列表,参数就像一个占位符,当函数被调用时,你可以将值传递给参数,这个值被称为实际参数。参数列表指定的是参数类型、顺序、及参数个数。参数是可选的,也就是说函数也可以不包含参数 返回类型,函数返回一列值。return_types 是该列值的数据类型。有些功能不需要返回值,这种情况下 return_types 不是必须的。 这里以一个加法的栗子说明: func add (a int,b int) int { var sum int = a + b return sum } func main() { //函数调用 cd := add(10,20) fmt.Println(cd) } 输出:30 下面再来写一个有多个返回值的 func add(a int, b int) (int,string){ var sum int = a + b str := strconv.Itoa(a) return sum,str } func main() { cd,str := add(100,200) fmt.Println("cd值为:",cd,str) } 输出:cd值为: 300 100 如果一个函数有多个返回值而你只想要其中的一个或几个,那么你不想要的返回值可以用下划线:_ 替代,也就是匿名变量 eg: cd, str := add(100,200) 此时不想要str 则改为: cd, _ := add(100,200)
-
变量的作用域
Go语言变量再三个地方声明: 1. 函数内——局部变量 2. 函数外——全局变量 3. 函数中——形式参数 与java定义类似不多解释
-
Go 语言指针
• 默认值 nil,没有 NULL 常量。
• 操作符 "&" (取地址符) 取变量地址,"*" (取值符)透过指针访问目标对象。
• 不支持指针运算,不支持 "->" 运算符,直接用 "." 访问目标成员。Go 支持指针。指针是保存值的地址的地方。 一个指针用 * 定义 指针声明: var name *类型 package main var ip *int /* 指向整型*/ //声明一个int值得指针变量 var fp *float32 /* 指向浮点型 */ var sp *string /* 指向字符串类型 */ func main() { } 根据数据类型定义指针。 例: var ap *int 上面的 ap 是指向整数类型的指针。& 运算符可用于获取变量的地址。 a := 12 ap = &a 可以使用 * 运算符访问指针指向的值: fmt.Println(*ap) // => 12 如何使用指针? 指针使用流程: 定义指针变量。 为指针变量赋值。 访问指针变量中指向地址的值。 在指针类型前面加上 * 号(前缀)来获取指针所指向的内容。
-
举个栗子
package main import "fmt" func main() { var a int = 20 /* 声明实际变量 */ var ip *int /* 声明指针变量 */ ip = &a /* 指针变量的存储地址 */ fmt.Printf("a 变量的地址是: %x\n", &a) /* 指针变量的存储地址 */ fmt.Printf("ip 变量的存储地址: %x\n", ip) /* 使用指针访问值 */ fmt.Printf("*ip 变量的值: %d\n", *ip) } 输出结果: a 变量的地址是: c420012058 ip 变量的存储地址: c420012058 *ip 变量的值: 20 在将结构体作为参数传递或者为已定义类型声明方法时,通常首选指针。 传递值时,实际复制的值意味着更多的内存 传递指针后,函数更改的值将反映在方法 / 函数调用者中。 例子: func increment(i *int) { *i++ } func main() { i := 10 increment(&i) fmt.Println(i) } //=> 11 上面那个栗子表示将i 用指针的形式再函数中加1,更改了i本身的值
-
直接用指针访问目标对象成员:
直接用指针访问目标对象成员: package main import ( "fmt" ) func main() { type data struct{ a int } var d = data{1234} var p *data p = &d fmt.Printf("%p, %v\n", p, p.a) // 直接用指针访问目标对象成员,无须转换。 } 输出结果: 0xc420012058, 1234 这种 .a 的形式有点类似于java中对象.变量的感觉,很熟悉,这样理解会方便一些 注意: 1. 不能对指针做加减法等运算。 2. 可以在 unsafe.Pointer 和任意类型指针间进 转换。 3. 将 Pointer 转换成 uintptr,可变相实现指针运算。
Go 空指针 nil
-
当一个指针被定义后没有分配到任何变量时,它的值为 nil。
nil 指针也称为空指针。 nil在概念上和其它语言的null、None、nil、NULL一样,都指代零值或空值。 一个指针变量通常缩写为 ptr 即 Pointer。 实例: package main import "fmt" func main() { var ptr *int /* %x 指十六进制,小写字母,每字节两个字符*/ fmt.Printf("ptr 的值为 : %x\n", ptr) } 输出结果: ptr 的值为 : 0
-
空指针判断:
package main import ( "fmt" ) func main() { var ptr1 *int var i int = 1 ptr2 := &i if ptr1 == nil { fmt.Println("prt1 是空指针") } if ptr2 != nil { fmt.Println("prt2 不是空指针 值为:") } } 输出结果: prt1 是空指针 prt2 不是空指针 指针记录到这里我稍微总结一下: 和C语言中指针类似,存储的是变量的地址值,我们无法直接给指针变量赋值 但是我们先定义一个变量之后将其地址取出: 如何取? 用 & 取 &变量 取出后我们把将要赋值的指针地址指向这个变量 ptr = &变量 这样就实现了给指针赋值 之后 *ptr 就可取出指针的值
请大家记住这个步骤:
-
指针声明格式如下:
var name *类型
-
如何使用指针?
指针使用流程:
定义指针变量。
为指针变量赋值。
访问指针变量中指向地址的值。
在指针类型前面加上 * 号(前缀)来获取指针所指向的内容。
-
Go 指针数组
-
声明指针数组
var ptr [MAX]*int; ptr 为整型指针数组。因此每个元素都指向了一个值。以下实例的三个整数将存储在指针数组中: package main import "fmt" const MAX int = 3 func main() { a := []int{9, 99, 999} var i int var ptr [MAX]*int for i = 0; i < MAX; i++ { ptr[i] = &a[i] /* 整数地址赋值给指针数组 */ } for i = 0; i < MAX; i++ { fmt.Printf("a[%d] = %d\n", i, *ptr[i]) } } 输出结果: a[0] = 9 a[1] = 99 a[2] = 999 如果一个指针变量存放的又是另一个指针变量的地址,则称这个指针变量为指向指针的指针变量。 当定义一个指向指针的指针变量时,第一个指针存放第二个指针的地址,第二个指针存放变量的地址: 指向指针的指针变量声明格式如下: var ptr **int 以上指向指针的指针变量为整型。 访问指向指针的指针变量值需要使用两个 * 号,如下所示: package main import "fmt" func main() { var a int var ptr *int var pptr **int a = 3000 /* 指针 ptr 地址 */ ptr = &a /* 指向指针 ptr 地址 */ pptr = &ptr /* 获取 pptr 的值 */ fmt.Printf("变量 a = %d\n", a) fmt.Printf("指针变量 *ptr = %d\n", *ptr) fmt.Printf("指向指针的指针变量 **pptr = %d\n", **pptr) } 输出结果: 变量 a = 3000 指针变量 *ptr = 3000 指向指针的指针变量 **pptr = 3000
请关注我的个人博客
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: