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\n", book.title);
    fmt.Printf( "Book author : %s\n", book.author);
    fmt.Printf( "Book subject : %s\n", book.subject);
    fmt.Printf( "Book book_id : %d\n", 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的值

  

 
 
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM