欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

go语言的结构体指针

程序员文章站 2022-07-02 16:38:32
Go 语言结构体 Go 语言中数组可以存储同一类型的数据,但在结构体中我们可以为不同项定义不同的数据类型。 结构体是由一系列具有相同类型或不同类型的数据构成的数据集合。 结构体表示一项记录,比如保存图书馆的书籍记录,每本书有以下属性: Title :标题 Author : 作者 Subject:学科 ......
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的值