• Go语言之自定义类型与指针


    Go 语言自定义类型与指针

    Go 语言指针

    Go 语言指针

    变量是一种使用方便的占位符,用于引用计算机内存地址。

    Go 语言的取地址符是 &,放到一个变量前使用就会返回相应变量的内存地址。

    package main
    
    import "fmt"
    
    func main() {
    
    	var a int = 10
    	fmt.Printf("%x 
    ", &a)
    }
    //c000010090
    

    什么是指针

    一个指针变量指向了一个值的内存地址。

    类似于变量和常量,在使用指针前你需要声明指针。指针声明格式如下:

    var var_name *var-type
    

    var-type 为指针类型,var_name 为指针变量名,* 号用于指定变量是作为一个指针。以下是有效的指针声明:

    var ip *int        /* 指向整型*/
    var fp *float32    /* 指向浮点型 */
    

    如何使用指针

    指针使用流程:

    • 定义指针变量。
    • 为指针变量赋值。
    • 访问指针变量中指向地址的值。

    在指针类型前面加上 * 号(前缀)来获取指针所指向的内容

    package main
    
    import "fmt"
    
    func main() {
    
    	var a int = 20
    	var ip *int //声明一个整型的指针
    	ip = &a
    	fmt.Println(*ip)   //通过指针访问地址
    	fmt.Printf("%x 
    ", &a) // a变量的内存地址
    	fmt.Println(ip)   //ip存储的是a变量的内存地址
    	fmt.Printf("%x 
    ", ip)   
    
    }
    """
    20
    c000010090
    0xc000010090
    c000010090
    """
    

    创建指针

    new(类型)
    new() 函数可以创建一个对应类型的指针,创建过程会分配内存,被创建的指针指向默认值
    
    package main
    
    import "fmt"
    
    func main() {
    	str := new(string)
    	*str = "hello"
    	fmt.Println(*str)
    }
    
    PS D:goprogramgosrcday05> go run .lianxi.go
    hello
    

    Go 空指针

    当一个指针被定义后没有分配到任何变量时,它的值为 nil。

    nil 指针也称为空指针。

    nil在概念上和其它语言的null、None、nil、NULL一样,都指代零值或空值。

    一个指针变量通常缩写为 ptr。

    查看以下实例:

    package main
    
    import "fmt"
    
    func main() {
    	var p *int
    	fmt.Printf("%x 
    ", p)
    	fmt.Printf("%d 
    ", *p)
    }
    """
    0
    panic: runtime error: invalid memory address or nil pointer dereference
    [signal 0xc0000005 code=0x0 addr=0x0 pc=0x49c104]
    
    goroutine 1 [running]:
    main.main()
            D:/goprogram/go/src/day05/function.go:8 +0x94
    """
    当访问空指针时,会报错,因为指针的内存地址为0,避免有空指针
    

    空指针判断:

    package main
    
    import "fmt"
    
    func main() {
    	var p *int
    	fmt.Printf("%x 
    ", p)
    	// fmt.Printf("%d 
    ", *p)
    	if p == nil {
    		fmt.Println("空指针")
    	}
    }
    
    
    内容 描述
    Go 指针数组 你可以定义一个指针数组来存储地址
    Go 指向指针的指针 Go 支持指向指针的指针
    Go 向函数传递指针参数 通过引用或地址传参,在函数调用时可以改变其值

    go指针数组

    声明整型指针数组:

    var ptr [MAX]*int;
    

    ptr 为整型指针数组。因此每个元素都指向了一个值。以下实例的三个整数将存储在指针数组中:

    package main
    
    import "fmt"
    
    const Max int = 3
    
    func main() {
    	a := []int{10, 100, 200}
    	var p [Max]*int //声明整型指针数组
    	for i := 0; i < Max; i++ {
    		p[i] = &a[i]
    	}
    
    	for i := 0; i < Max; i++ {
    		fmt.Printf("p[%d] = %d
    ", i, *p[i])
    	}
    
    }
    """
    p[0] = 10
    p[1] = 100
    p[2] = 200
    """
    

    创建指针数组的时候,不适合用 range 循环。

    错误代码:

    package main
    
    import "fmt"
    
    const Max int = 3
    
    func main() {
    	a := [Max]int{10, 100, 200}
    	var p [Max]*int //声明整型指针数组
    	// for i := 0; i < Max; i++ {
    	// 	p[i] = &a[i]
    	// }
    
    	// for i := 0; i < Max; i++ {
    	// 	fmt.Printf("p[%d] = %d
    ", i, *p[i])
    	// }
    	for i, x := range &a {
    		p[i] = &x
    	}
    	for i, x := range p {
    		fmt.Printf("指针数组:索引:%d 值:%d 值的内存地址:%d
    ", i, *x, x)
    	}
    }
    """
    PS D:goprogramgosrcday05> go build -o funtion.exe
    PS D:goprogramgosrcday05> .funtion.exe
    指针数组:索引:0 值:200 值的内存地址:824633786512
    指针数组:索引:1 值:200 值的内存地址:824633786512
    指针数组:索引:2 值:200 值的内存地址:824633786512
    
    从结果中我们发现内存地址都一样,而且值也一样。怎么回事?
    
    这个问题是range循环的实现逻辑引起的。跟for循环不一样的地方在于range循环中的x变量是临时变量。range循环只是将值拷贝到x变量中。因此内存地址都是一样的。
    """
    
    

    正确代码:

    package main
    
    import "fmt"
    
    const Max int = 3
    
    func main() {
    	a := [Max]int{10, 100, 200}
    	var p [Max]*int //声明整型指针数组
    	for i := 0; i < Max; i++ {
    		p[i] = &a[i]
    	}
    
    	// for i := 0; i < Max; i++ {
    	// 	fmt.Printf("p[%d] = %d
    ", i, *p[i])
    	// }
    	// for i, x := range &a {
    	// 	p[i] = &x
    	// }
    	for i, x := range p {
    		fmt.Printf("指针数组:索引:%d 值:%d 值的内存地址:%d
    ", i, *x, x)
    	}
    }
    """
    PS D:goprogramgosrcday05> go build -o funtion.exe
    PS D:goprogramgosrcday05> .funtion.exe
    指针数组:索引:0 值:10 值的内存地址:824634122560
    指针数组:索引:1 值:100 值的内存地址:824634122568
    指针数组:索引:2 值:200 值的内存地址:824634122576
    """
    

    Go 语言指向指针的指针

    如果一个指针变量存放的又是另一个指针变量的地址,则称这个指针变量为指向指针的指针变量。

    当定义一个指向指针的指针变量时,第一个指针存放第二个指针的地址,第二个指针存放变量的地址:

    向指针的指针变量声明格式如下:

    var ptr **int;
    

    以上指向指针的指针变量为整型。

    访问指向指针的指针变量值需要使用两个 * 号,如下所示:

    package main
    
    import "fmt"
    
    const Max int = 3
    
    const (
    	n1 = iota
    )
    
    func main() {
    	var a int
    	var p *int
    	var pp **int
    	a = 3000
    	p = &a
    	pp = &p
    	fmt.Printf("&a=%x  a=%d
    ", &a, a)
    	fmt.Printf("p=%x  *p=%d
    ", p, *p)
    	fmt.Printf("pp=%x  *pp=%d
    ", pp, *pp)
    	fmt.Printf("**pp=%d
    ", **pp)
    }
    
    
    运行结果
    PS D:goprogramgosrcday05> go build -o funtion.exe
    PS D:goprogramgosrcday05> .funtion.exe
    &a=c000010090  a=3000
    p=c000010090  *p=3000
    pp=c000006028  *pp=824633786512
    **pp=3000
    

    Go 语言指针作为函数参数

    Go 语言允许向函数传递指针,只需要在函数定义的参数上设置为指针类型即可

    package main
    
    import "fmt"
    
    const Max int = 3
    
    func swap(x *int, y *int) {
    	fmt.Println(x)
    	fmt.Println(y)
    	var temp int
    	temp = *x //*(&a)
    	*x = *y   //*(&a)=*(&b)
    	*y = temp //*(&b) = 100
    }
    
    func main() {
    	var a int = 100
    	var b int = 200
    	swap(&a, &b)
    	fmt.Println(a)
    	fmt.Println(b)
    
    }
    
    
    运行结果
    0xc000010090
    0xc000010098
    200
    100
    

    简便方式,采用python中的解构

    package main
    
    import "fmt"
    
    const Max int = 3
    
    func swap(x *int, y *int) {
    	// var temp int
    	// temp = *x //*(&a)
    	// *x = *y   //*(&a)=*(&b)
    	// *y = temp //*(&b) = 100
    	// 简便方式
    	*x, *y = *y, *x
    }
    
    func main() {
    	var a int = 100
    	var b int = 200
    	swap(&a, &b)
    	fmt.Println(a)
    	fmt.Println(b)
    
    }
    
    

    案例:使用指针变量获取命令行的输入信息

    Go语言内置的 flag 包实现了对命令行参数的解析,flag 包使得开发命令行工具更为简单

    package main
    
    import (
    	"flag"
    	"fmt"
    	"os"
    )
    
    var mode = flag.String("mode", "", "process mode")
    
    func main() {
    	//解析命令行参数
    	fmt.Println(os.Args[1:])
    	flag.Parse()
    	fmt.Println(*mode)
    }
    
    """
    fast
    PS D:goprogramgosrcday05> go run .lianxi.go --mode=fast
    [--mode=fast]
    fast
    PS D:goprogramgosrcday05> go run .lianxi.go --mode=fast                       t]
    [C:Users32639AppDataLocalTempgo-build599453026001exelianxi.exe --mode=fast]
    

    Go 语言结构体

    Go 语言结构体

    Go 语言中数组可以存储同一类型的数据,但在结构体中我们可以为不同项定义不同的数据类型。

    结构体是由一系列具有相同类型或不同类型的数据构成的数据集合

    定义结构体

    结构体定义需要使用 type 和 struct 语句。struct 语句定义一个新的数据类型,结构体中有一个或多个成员。type 语句设定了结构体的名称。结构体的格式如下:

    type struct_variable_type struct {
       member definition
       member definition
       ...
       member definition
    }
    

    一旦定义了结构体类型,它就能用于变量的声明,语法格式如下:

    variable_name := structure_variable_type {value1, value2...valuen}
    或
    variable_name := structure_variable_type { key1: value1, key2: value2..., keyn: valuen}
    
    package main
    
    import "fmt"
    type Books struct {
    	title   string
    	author  string
    	subject string
    	book_id int
    }
    
    func main() {
    	fmt.Println(Books{"Go 语言", "www.runoob.com", "Go 语言教程", 6495407})
    	b := Books{"Go 语言", "www.runoob.com", "Go 语言教程", 6495407}
    
    	fmt.Println(b.title)
       // 忽略的字段为 0 或 空
       fmt.Println(Books{title: "Go 语言", author: "www.runoob.com"})
    }
    

    访问结构体成员

    如果要访问结构体成员,需要使用点号 . 操作符,格式为:

    结构体.成员名"
    

    结构体类型变量使用 struct 关键字定义,实例如下:

    package main
    
    import "fmt"
    
    type Books struct {
       title string
       author string
       subject string
       book_id int
    }
    
    func main() {
       var Book1 Books        /* 声明 Book1 为 Books 类型 */
       var Book2 Books        /* 声明 Book2 为 Books 类型 */
    
       /* book 1 描述 */
       Book1.title = "Go 语言"
       Book1.author = "www.runoob.com"
       Book1.subject = "Go 语言教程"
       Book1.book_id = 6495407
    
       /* book 2 描述 */
       Book2.title = "Python 教程"
       Book2.author = "www.runoob.com"
       Book2.subject = "Python 语言教程"
       Book2.book_id = 6495700
    
       /* 打印 Book1 信息 */
       fmt.Printf( "Book 1 title : %s
    ", Book1.title)
       fmt.Printf( "Book 1 author : %s
    ", Book1.author)
       fmt.Printf( "Book 1 subject : %s
    ", Book1.subject)
       fmt.Printf( "Book 1 book_id : %d
    ", Book1.book_id)
    
       /* 打印 Book2 信息 */
       fmt.Printf( "Book 2 title : %s
    ", Book2.title)
       fmt.Printf( "Book 2 author : %s
    ", Book2.author)
       fmt.Printf( "Book 2 subject : %s
    ", Book2.subject)
       fmt.Printf( "Book 2 book_id : %d
    ", Book2.book_id)
    }
    """
    Book 1 title : Go 语言
    Book 1 author : www.runoob.com
    Book 1 subject : Go 语言教程
    Book 1 book_id : 6495407
    Book 2 title : Python 教程
    Book 2 author : www.runoob.com
    Book 2 subject : Python 语言教程
    Book 2 book_id : 6495700
    """
    

    结构体作为函数参数

    你可以像其他数据类型一样将结构体类型作为参数传递给函数。并以以上实例的方式访问结构体变量:

    **package** main
    
    **import** "fmt"
    
    **type** Books struct {
       title string
       author string
       subject string
       book_id int
    }
    
    func main() {
       **var** Book1 Books        */* 声明 Book1 为 Books 类型 */*
       **var** Book2 Books        */* 声明 Book2 为 Books 类型 */*
    
       */* book 1 描述 */*
       Book1.title = "Go 语言"
       Book1.author = "www.runoob.com"
       Book1.subject = "Go 语言教程"
       Book1.book_id = 6495407
    
       */* book 2 描述 */*
       Book2.title = "Python 教程"
       Book2.author = "www.runoob.com"
       Book2.subject = "Python 语言教程"
       Book2.book_id = 6495700
    
       */* 打印 Book1 信息 */*
       printBook(Book1)
    
       */* 打印 Book2 信息 */*
       printBook(Book2)
    }
    
    func printBook( book Books ) {
       fmt.Printf( "Book title : %s**
    **", book.title)
       fmt.Printf( "Book author : %s**
    **", book.author)
       fmt.Printf( "Book subject : %s**
    **", book.subject)
       fmt.Printf( "Book book_id : %d**
    **", book.book_id)
    }
    

    以上实例执行运行结果为:

    Book title : Go 语言
    Book author : www.runoob.com
    Book subject : Go 语言教程
    Book book_id : 6495407
    Book title : Python 教程
    Book author : www.runoob.com
    Book subject : Python 语言教程
    Book book_id : 6495700
    

    结构体指针

    你可以定义指向结构体的指针类似于其他指针变量,格式如下:

    var struct_pointer *Books
    

    以上定义的指针变量可以存储结构体变量的地址。查看结构体变量地址,可以将 & 符号放置于结构体变量前:

    struct_pointer = &Book1
    

    使用结构体指针访问结构体成员,使用 "." 操作符:

    struct_pointer.title
    
    package main
    
    import "fmt"
    
    type Books struct {
       title string
       author string
       subject string
       book_id int
    }
    
    func main() {
       var Book1 Books        /* Declare Book1 of type Book */
       var Book2 Books        /* Declare Book2 of type Book */
    
       /* book 1 描述 */
       Book1.title = "Go 语言"
       Book1.author = "www.runoob.com"
       Book1.subject = "Go 语言教程"
       Book1.book_id = 6495407
    
       /* book 2 描述 */
       Book2.title = "Python 教程"
       Book2.author = "www.runoob.com"
       Book2.subject = "Python 语言教程"
       Book2.book_id = 6495700
    
       /* 打印 Book1 信息 */
       printBook(&Book1)
    
       /* 打印 Book2 信息 */
       printBook(&Book2)
    }
    func printBook( book *Books ) {
       fmt.Printf( "Book title : %s
    ", book.title)
       fmt.Printf( "Book author : %s
    ", book.author)
       fmt.Printf( "Book subject : %s
    ", book.subject)
       fmt.Printf( "Book book_id : %d
    ", book.book_id)
    }
    """
    Book title : Go 语言
    Book author : www.runoob.com
    Book subject : Go 语言教程
    Book book_id : 6495407
    Book title : Python 教程
    Book author : www.runoob.com
    Book subject : Python 语言教程
    Book book_id : 6495700
    """
    

    结构体是作为参数的值传递:

    package main
    
    import "fmt"
    
    type Books struct {
        title string
        author string
        subject string
        book_id int
    }
    
    func changeBook(book Books) {
        book.title = "book1_change"
    }
    
    func main() {
        var book1 Books
        book1.title = "book1"
        book1.author = "zuozhe"
        book1.book_id = 1
        changeBook(book1)
        fmt.Println(book1)
    }
    

    结果为:

    {book1 zuozhe  1}
    

    如果想在函数里面改变结果体数据内容,需要传入指针:

    package main
    
    import "fmt"
    
    type Books struct {
        title string
        author string
        subject string
        book_id int
    }
    
    func changeBook(book *Books) {
        book.title = "book1_change"
    }
    
    func main() {
        var book1 Books
        book1.title = "book1"
        book1.author = "zuozhe"
        book1.book_id = 1
        changeBook(&book1)
        fmt.Println(book1)
    }
    

    结果为:

    {book1_change zuozhe  1}
    

    Go 语言常用语法错误

    1、开大括号不能放在单独的一行

    错误代码:

    package main
    
    import "fmt"
    
    func main() 
    { 
        fmt.Println("hello world!")
    }
    

    编译错误:

    ./main.go:5:6: missing function body for "main"
    ./main.go:6:1: syntax error: unexpected semicolon or newline before {
    

    正确代码:

    package main
    
    import "fmt"
    
    func main() {
        fmt.Println("hello world!")
    }
    

    2、未使用的变量

    如果你有未使用的局部变量,代码将编译失败。
    如果你给未使用的变量分配了一个新的值,代码还是会编译失败。你需要在某个地方使用这个变量,才能让编译器愉快的编译。

    错误代码:

    package main
    
    var gvar int
    
    func main() {
        var one int
        two := 2
        var three int
        three = 3
    }
    

    编译错误:

    ./main.go:6:6: one declared and not used
    ./main.go:7:9: two declared and not used
    ./main.go:8:6: three declared and not used
    

    正确代码:

    package main
    
    import "fmt"
    
    func main() {
        var one int
        _ = one
        two := 2
        fmt.Println(two)
        var three int
        three = 3
        one = three
        var four int
        four = four
    }
    
    // 另外可以选择是注释掉或者移除未使用的变量
    

    3、未使用的Imports

    如果你引入一个包,而没有使用其中的任何函数、接口、结构体或者变量的话,代码将会编译失败。
    如果你真的需要引入的包,你可以添加一个"_"下划线标记符,来作为这个包的名字,从而避免编译失败。下滑线标记符用于引入,但不使用。

    错误代码:

    package main
    
    import (
        "fmt"
        "log"
        "time"
    )
    
    func main() {
    }
    

    编译错误:

    ./main.go:4:2: imported and not used: "fmt"
    ./main.go:5:2: imported and not used: "log"
    ./main.go:6:2: imported and not used: "time"
    

    正确代码:

    package main
    
    import (
        _ "fmt"
        "log"
        "time"
    )
    
    var _ = log.Println
    
    func main() {
        _ = time.Now
    }
    
    // 另外可以选择是移除或者注释掉未使用的imports
    

    4、":="简式的变量声明仅可以在函数内部使用

    错误代码:

    package main
    
    myvar := 1 
    
    func main() {  
    }
    

    编译错误:

    ./main.go:3:1: syntax error: non-declaration statement outside function body
    

    正确代码:

    package main
    
    var myvar = 1
    
    func main() {
    }
    

    5、使用简式声明重复声明变量

    你不能在一个单独的声明中重复声明一个变量,但在多变量声明中这是允许的,其中至少要有一个新的声明变量。
    重复变量需要在相同的代码块内,否则你将得到一个隐藏变量。

    错误代码:

    package main
    
    func main() {
        one := 0
        one := 1
    }
    

    编译错误:

    ./main.go:5:6: no new variables on left side of :=
    

    正确代码:

    package main
    
    func main() {
        one := 0
        one, two := 1, 2
        one, two = two, one
    }
    

    6、Go语言命名区分大小写

    错误代码:

    package main
    
    import "fmt"
    
    func main() {
        fmt.println("Hello world")
    }
    
    // 以下代码都是不正确的:
    // Package main
    // iMport "fmt"
    // import "Fmt"
    // Func main() {}
    // Fmt.Println
    // fmt.println
    

    编译错误:

    ./main.go:6:2: cannot refer to unexported name fmt.println
    ./main.go:6:2: undefined: fmt.println
    

    正确代码:

    package main
    
    import "fmt"
    
    func main() {
        fmt.Println("Hello world")
    }
    

    7、Go语言中分号分行

    错误代码:

    package main
    
    import "fmt"
    
    func main() {
        fmt.Println("Hello world") fmt.Println("Hi again")
    }
    

    编译错误:

    ./main.go:6:29: syntax error: unexpected fmt at end of statement
    

    正确代码:

    package main
    
    import "fmt"
    
    func main() {
        fmt.Println("Hello world")
    
        //解决以上问题,可以将上述的两条语句放在两行
        fmt.Println("Hi again") 
    
        //可以将两条语句用分号结束
        fmt.Println("Hello world");fmt.Println("Hi again") 
        test()
    }
    
    func test() { 
        //因此在Go语言中,分号能省则省,如果必须使用时,添加上也不会出错。
        fmt.Println("Hello world");fmt.Println("Hi again");
    };
    

    8、Go语言中无效的分号

    错误代码:

    package main
    
    import "fmt";;
    
    func main() {
        fmt.Println("Hello world")
    }
    

    编译错误:

    ./main.go:3:14: syntax error: non-declaration statement outside function body
    

    正确代码:

    package main
    
    import "fmt";
    
    func main() {
        fmt.Println("Hello world")
    }
    

    9、Go语言中注意变量作用域

    错误代码:

    package main
    
    var num int
    
    func main() {
        str := "hello world"
        if true {
            var b bool
        }
        println(num)
        println(str)
        println(b)
    }
    

    编译错误:

    ./main.go:12:10: undefined: b
    

    正确代码:

    package main
    
    var num int
    
    func main() {
        str := "hello world"
        if true {
            var b bool
            println(b)
        }
        println(num)
        println(str)
    }
    

    10、偶然的变量隐藏

    短式变量声明的语法如此的方便(尤其对于那些使用过动态语言的开发者而言),很容易让人把它当成一个正常的分配操作。如果你在一个新的代码块中犯了这个错误,将不会出现编译错误,但你的应用将不会做你所期望的事情。

    package main
    
    import "fmt"
    
    func main() {
        x := 1
        fmt.Println(x) // 1
        {
            fmt.Println(x) // 1
            x := 2
            fmt.Println(x) // 2
        }
        fmt.Println(x) // 1 
    }
    

    运行结果:

    1
    1
    2
    1
    

    即使对于经验丰富的Go开发者而言,这也是一个非常常见的陷阱,但又很难发现。

    你可以使用 vet命令来发现一些这样的问题。 默认情况下, vet不会执行这样的检查,你需要设置-shadow参数:
    命令:go tool vet -shadow your_file.go

    go tool vet -shadow main.go
    main.go:10: declaration of "x" shadows declaration at main.go:6
    

    11、不使用显式类型,无法使用“nil”来初始化变量

    nil标志符用于表示interface、函数、maps、slices和channels的“零值”。如果你不指定变量的类型,编译器将无法编译你的代码,因为它猜不出具体的类型。

    错误代码:

    package main
    
    func main() {
        var x = nil
        _ = x
    }
    

    编译错误:

    ./main.go:4:6: use of untyped nil
    

    正确代码:

    package main
    
    func main() {
        var x interface{} = nil
        _ = x
    }
    

    12、使用“nil” Slices and Maps

    在一个nil的slice中添加元素是没问题的,但对一个map做同样的事将会生成一个运行时的panic。

    正确代码:

    package main
    
    func main() {
        var s []int
        s = append(s, 1)
    }
    

    错误代码:

    package main
    
    import (
        "fmt"
    )
    
    func main() {
        var m map[int]int
        m[1] = 1
        fmt.Println(m)
    }
    

    运行错误:

    panic: assignment to entry in nil map
    

    正确代码:

    package main
    
    import (
        "fmt"
    )
    
    func main() {
        var m map[int]int
        m = make(map[int]int)
        m[1] = 1
        fmt.Println(m)
    }
    

    13、Map的容量

    map 只有 len操作, 没有 cap 操作

    错误代码:

    package main
    
    import (
        "fmt"
    )
    
    func main() {
        m := map[int]string{1: "a", 2: "b", 3: "c"}
        cap := cap(m)
        fmt.Println(cap)
    }
    

    编译错误:

    ./main.go:9:12: invalid argument m (type map[int]string) for cap
    

    正确代码:

    package main
    
    import (
        "fmt"
    )
    
    func main() {
        m := map[int]string{1: "a", 2: "b", 3: "c"}
        len := len(m)
        fmt.Println(len)
    }
    

    14、字符串不会为nil

    这对于经常使用nil分配字符串变量的开发者而言是个需要注意的地方。

    package main
    
    func main() {
        var x string = nil
        if x == nil {
            x = "default"
        }
    }
    

    编译错误:

    ./main.go:4:6: cannot use nil as type string in assignment
    ./main.go:5:7: invalid operation: x == nil (mismatched types string and nil)
    

    正确代码:

    package main
    
    func main() {
        var x string
        if x == "" {
            x = "default"
        }
    }
    
  • 相关阅读:
    一次线上问题引发的对于C#中相等判断的思考
    Node中的模块引入机制
    Node 各个版本支持ES2015特性的网站
    使用Chrome 中的 ssh 插件登陆 linux 服务器
    vmWare 虚机文件不能启动的事故处理
    JaveScript 中使用 XSLT转换XML文档
    浏览器上的坐标体系相关概念(客户区,页面,屏幕)
    visual Studio 中使用正则表达式来进行查找替换
    JavaScript 执行环境及作用域
    Laravel save部分字段失效的bug问题解决
  • 原文地址:https://www.cnblogs.com/heych/p/12579430.html
Copyright © 2020-2023  润新知