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中函数为一等公民:

    1. 函数本身可以作为值来传递
    2. 支持匿名函数和闭包
    3. 函数可以满足接口
  • 如何声明函数(函数定义)

    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 就可取出指针的值
    

    请大家记住这个步骤:

    1. 指针声明格式如下:

      var name *类型

    2. 如何使用指针?

      指针使用流程:
      定义指针变量。
      为指针变量赋值。
      访问指针变量中指向地址的值。
      在指针类型前面加上 * 号(前缀)来获取指针所指向的内容。

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 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!