首页 > 其他分享 >golang:方法接收者带星号和不带星号的区别

golang:方法接收者带星号和不带星号的区别

时间:2024-12-14 13:10:41浏览次数:9  
标签:星号 fmt 接收者 golang person Println 方法 Age

一,说明:

  • 不带星号的方法‌:这些方法定义在值接收者(value receiver)上。
    当你调用这些方法时,会操作该值的副本。
    如果方法内部修改了接收者,这些修改不会反映到原始值上。

  • 带星号的方法‌:这些方法定义在指针接收者(pointer receiver)上。
    当你调用这些方法时,会操作原始值的指针。
    如果方法内部修改了接收者指向的值,这些修改会反映到原始值上。

 

二,代码:

package main

import (
    "fmt"
    "reflect"
)

func isPointer(v interface{}) bool {
    return reflect.ValueOf(v).Kind() == reflect.Ptr
}

// 定义一个结构体
type Person struct {
    Name string
    Age  int
}


// 定义一个带星号的方法(指针接收者)
func (p *Person) IncrementAge() {
    fmt.Printf("星号方法中 p是否指针: %v\n", isPointer(p))
    fmt.Printf("星号方法中 p的地址:%p\n", &p)
    fmt.Printf("星号方法中 p指向的地址:%p\n", &*p)
    p.Age++
}

// 定义一个不带星号的方法(值接收者)
func (p Person) PrintAge() {
    fmt.Printf("方法1中 p是否指针: %v\n", isPointer(p))
    fmt.Printf("方法1中 p的地址:%p\n", &p)
    fmt.Println("方法1改变前:",p.Age)         // 输出:31
    p.Age++     //此时的p是一个副本,修改后不会影响调用它的对象
    fmt.Println("方法1改变后:",p.Age)          // 输出:32
}


// 定义一个不带星号的方法2(值接收者)
func (p Person) PrintAge2() {
    fmt.Printf("方法2中 p是否指针: %v\n", isPointer(p))
    fmt.Printf("方法2中 p的地址:%p\n", &p)
    fmt.Println("方法2改变前:",p.Age)       // 输出:31
    p.Age+=5     //此时的p是一个副本,修改后不会影响调用它的对象
    fmt.Println("方法2改变后:",p.Age)      // 输出:36
}


func main() {
    person := Person{Name: "Alice", Age: 30}
    fmt.Printf("person对象的地址:%p\n", &person)
    fmt.Println("星号方法调用前:",person.Age) // 输出:31
    person.IncrementAge() // 调用带星号方法
    fmt.Println("星号方法调用后:",person.Age) // 输出:31


    (&person).IncrementAge() // 调用带星号方法2
    fmt.Println("星号方法调用后2:",person.Age) // 输出:31

    person.PrintAge()
    fmt.Println("person.Age:",person.Age) // 输出:31

    person.PrintAge2()
    fmt.Println("person.Age:",person.Age) // 输出:31
}

 

三,测试效果:

$ go run main.go 
person对象的地址:0xc00009c000
星号方法调用前: 30
星号方法中 p是否指针: true
星号方法中 p的地址:0xc000088040
星号方法中 p指向的地址:0xc00009c000
星号方法调用后: 31
星号方法中 p是否指针: true
星号方法中 p的地址:0xc000088048
星号方法中 p指向的地址:0xc00009c000
星号方法调用后2: 32
方法1中 p是否指针: false
方法1中 p的地址:0xc00009c018
方法1改变前: 32
方法1改变后: 33
person.Age: 32
方法2中 p是否指针: false
方法2中 p的地址:0xc00009c030
方法2改变前: 32
方法2改变后: 37
person.Age: 32

 

标签:星号,fmt,接收者,golang,person,Println,方法,Age
From: https://www.cnblogs.com/architectforest/p/18599020

相关文章

  • golang:第三方库:用jordan-wright/email发送邮件
    一,安装第三方库:$goget-ugithub.com/jordan-wright/emailgo:downloadinggithub.com/jordan-wright/emailv4.0.1-0.20210109023952-943e75fe5223+incompatiblego:addedgithub.com/jordan-wright/emailv4.0.1-0.20210109023952-943e75fe5223+incompatible二,代码:1,发送......
  • Golang学习笔记_05——延迟调用
    Golang学习笔记_02——函数Golang学习笔记_03——匿名函数和闭包Golang学习笔记_04——递归函数文章目录延迟调用1.延迟调用1.1使用场景1.2示例2.panic2.1使用场景2.2示例3.recover3.1使用场景3.2示例源码延迟调用在Go语言中,延迟调用(defer)是一个......
  • Golang学习笔记_02——函数
    Golang测试功能应用Golang学习笔记_01——包函数文章目录函数1.定义2.返回值3.命名返回值4.可变参数源码Go语言中的函数是一种基本的编程结构,用于封装一段代码,以便在需要时多次调用。函数可以接收参数并返回结果,是实现代码复用和模块化编程的重要手段。1......
  • 写一个密码默认星号,但可以查看密码的输入框
    <!DOCTYPEhtml><html><head><title>密码输入框</title><style>#password-container{position:relative;}#show-password{position:absolute;top:50%;right:10px;transform:translateY(-50%);cursor:pointe......
  • 一行代码都不改,Golang 应用链路指标日志全知道!
    作者:刘子明(牧思)背景在此前,对Golang应用程序的监控通常需要对代码进行一定的改造,比如在代码中引入OpenTelemetry等SDK[1]。这样的改造通常会导致运维团队与研发团队之间的分歧。运维团队表示:“研发团队如果不接入相关的监控,作为运维团队我们很难摸清楚应用的运行状态并做......
  • 无法连接外网的机器部署VSCode&&Golang开发环境
    目标环境解释:开发使用的机器无法连接外网,导致直接使用go安装modules失败个人机器可以在内网中连接开发机器,并连接外网如果可以使用内网的go源,那就不用往下看了在一个无法连接外网的Linux工作机器上部署VSCode-golang开发环境实现步骤安装Golang在官网下载g......
  • 即时通讯在线客服系统源码-使用Golang Gin 和 Redis实现分布式webocket
    使用Go实现一个基于Gin框架和Redis的分布式WebSocket系统需要以下几个步骤:实现架构Gin处理HTTP/WebSocket请求Gin用于启动HTTP服务并处理WebSocket请求。RedisPub/SubRedis用于跨节点消息分发。WebSocket连接管理在服务内维护WebSocket连接池......
  • golang
    何为runtime?很多语言都有Runtime go的runtime特点没有虚拟机的概念Runtime作为程序的一部分打包进二进制产物Runtime随用户程序一起运行Runtime与用户程序没有明显界限,直接通过函数调用 内存管理能力垃圾回收能力(GC)超强的并发能力(协程调度) 总结:Go......
  • golang: 返回错误时打印堆栈
    一,默认的错误打印:1,定义函数://打印错误的堆栈信息funcPrintStackTrace(errerror){ //创建一个缓冲区用于存储堆栈信息 buf:=bytes.NewBuffer(nil) //获取当前goroutine的堆栈信息 fori:=0;;i++{ pc,file,line,ok:=runtime.Caller(i) if!ok{ ......
  • Golang教程第16篇(语言数组)
    Go语言数组Go语言提供了数组类型的数据结构。数组是具有相同唯一类型的一组已编号且长度固定的数据项序列,这种类型可以是任意的原始类型例如整型、字符串或者自定义类型。相对于去声明number0,number1,…,number99的变量,使用数组形式numbers[0],numbers[1]…,......