zoukankan      html  css  js  c++  java
  • go语言的结构体指针

    Go 语言结构体

    Go 语言中数组可以存储同一类型的数据,但在结构体中我们可以为不同项定义不同的数据类型。
     
    结构体是由一系列具有相同类型或不同类型的数据构成的数据集合。
     
    结构体表示一项记录,比如保存图书馆的书籍记录,每本书有以下属性:
     
    Title :标题
    Author : 作者
    Subject:学科
    ID:书籍ID
     
    定义结构体
    结构体定义需要使用 type 和 struct 语句。struct 语句定义一个新的数据类型,结构体有中有一个或多个成员。type 语句设定了结构体的名称。
     
     
    语法:
    type struct_variable_type struct {
       member definition;
       member definition;
       ...
       member definition;
    }
    

      

     
    //例子:
    type Books struct {
       title string
       author string
       subject string
       book_id int
    }
    

      

     
    那么就可以使用如下的定义方式:
    variable_name := structure_variable_type {value1, value2...valuen}
    variable_name := structure_variable_type { key1: value1, key2: value2..., keyn: valuen}
    

      

    // 例子:
    var book1 = Books {"Go 入门到放弃","yuantiankai","go系列教程",012231}
    

      

     
    访问结构体成员
    如果要访问结构体成员,需要使用点号 . 操作符,格式为:
    结构体.成员名
     
    //例子:
    fmt.Println(book1.author)
    fmt.Println(book1.title)
    

      

    结构体作为函数参数

    你可以像其他数据类型一样将结构体类型作为参数传递给函数。并以以上实例的方式访问结构体变量:
    //例子:
    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);
    }
    然后这个printBook函数可以在主函数中调用。
     

     

    结构体指针

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

      

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

      

     
    使用结构体指针访问结构体成员,使用 "." 操作符:
    struct_pointer.title;:
     
    //例子:
    var b *Books
     
    b = &Book1
    fmt.Println(b)    //&{Go 语言 www.runoob.com Go 语言教程 6495407}
    fmt.Println(*b)   //{Go 语言 www.runoob.com Go 语言教程 6495407}
    fmt.Println(&b)   //0xc000082018
    fmt.Println(Book1)    //{Go 语言 www.runoob.com Go 语言教程 6495407}
    

      

     
    //解释:
    其实跟普通的指针是一样的,只不过这次是指定的结构体的指针,在上面的例子中:
    var b *Books     //就是说b这个指针是Books类型的。
    b  = &Book1     //Book1是Books的一个实例化的结构,&Book1就是把这个结构体的内存地址赋给了b,
    *b         //那么在使用的时候,只要在b的前面加个*号,就可以把b这个内存地址对应的值给取出来了
    &b        // 就是取了b这个指针的内存地址,也就是b这个指针是放在内存空间的什么地方的。
    Book1       // 就是Book1这个结构体,打印出来就是它自己。也就是指针b前面带了*号的效果。
     
     
    //只有一个特殊的地方,尽管b所表示的是Book1对象的内存地址,但是,在从b对应的内存地址取属性值的时候,就不是*b.title了。而是直接使用b.title,这点很特殊,它的效果就相当于Book1.title:
    fmt.Println(b.title)   //Go 入门到放弃
    fmt.Println(Book1.title)   //Go 入门到放弃
    fmt.Println(b.author)   //yuantiankai
    fmt.Println(Book1.author)  //yuantiankai
     

    具体区别:
    比如我们要写一个函数修改结构体里的一个值,那么我们需要将修改过后的值返回出来,然后再重新赋值,比如这样:
    package main
     
    import "fmt"
     
    type Books struct {
        title string
        author string
        subject string
        book_id int
    }
     
    func changeBook(book Books) string {   //把book对象传进来,返回的值是string类型的,也就是将被修改的值返回出来。
        book.title = "book1_change"
        return book.title
    }
     
    func main() {
        var book1 Books;
        book1.title = "book1"
        book1.author = "zuozhe"
        book1.book_id = 1
        var res = changeBook(book1)   //然后在外面拿到被修改的值
        book1.title = res        // 再重新赋值
        fmt.Println(book1)
    }
    //结果为:
    {book1_change 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)   //将book1传进去,本意是想修改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) {  // 这个方法传入的参数一个Books类型的指针
        book.title = "book1_change"  //直接用指针.属性的方式,修改原地址的值。
    }
     
    func main() {
        var book1 Books;
        book1.title = "book1"
        book1.author = "zuozhe"
        book1.book_id = 1
        changeBook(&book1)   //将book1这个对象的内存地址传进去,
        fmt.Println(book1)
    }
    //结果为:
     
    {book1_change zuozhe  1}  //成功修改了book1的值
    

      

     
     
     
     
  • 相关阅读:
    360网盘书籍分享
    oracle11g字符集问题之一
    order by 的列名不能参数化,要拼sql
    oracle11g的冷热备份
    Spring 事务管理的使用
    Spring 事务管理的API
    事务总结
    Excel 单元格中内容的换行
    手动配置IP地址
    MyBatis 三剑客
  • 原文地址:https://www.cnblogs.com/haiguixiansheng/p/10613754.html
Copyright © 2011-2022 走看看