首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Go 语言基础入门教程 —— 函数篇:函数参和返回值

上篇教程我们介绍了 Go 语言中函数的基本定义和调用,其中也涉及到了函数参和返回值,只不过那里演示的是最简单的场景,今天我们就更复杂的参和返回值进行介绍。...按值参和引用Go 语言默认使用按值参来传递参数,也就是传递参数的一个副本,函数接收该参数后,可能在处理过程中对参数值做调整,但这不会影响原来的变量值,我们还是以上篇教程的 add 函数为基础作为示例...,需要通过引用参来完成,此时传递给函数的参数是一个指针,而指针代表的是原变量的地址,修改指针指向的值即修改变量地址中存储的值,所以原变量的值也会被修改(这种情况下,传递的是变量地址值的拷贝,所以从本质上来说还是按值参...: add(2, 6) = 8 在函数调用时,像切片(slice)、字典(map)、接口(interface)、通道(channel)这样的引用类型 默认使用引用参(即使没有显示的指出指针,类似 PHP...多返回值及返回值命名 Go 语言函数与其他编程语言一大不同之处在于支持多返回值,这在处理程序出错的时候非常有用,比如,如果上述 add 函数只支持非负整数相加,传入负数则会报错,换做是在其他语言 PHP

1.3K30

gin框架常用模块

(&p)的含义是:c.ShouldBindJSON是Gin框架中的一个函数,用于将HTTP请求的JSON格式的请求体解析为Go语言中的结构体对象。...这种写法适用于定义一个指针变量,需要在后续的代码中通过new()函数或其他方式对它进行初始化,才能使用该指针变量进行赋值、参等操作。 在后续传参时,两种写法的区别在于传递的值的类型不同。...对于第二种写法 var res *dao.BpCourseware,res是一个指向dao.BpCourseware类型的指针变量,需要将它的地址作为参数传递给需要的函数或方法。...例如,可以通过&res获取res变量的地址,然后将地址作为参数传递给需要的函数或方法。在函数或方法内部,可以通过*res获取指针指向的实际数据. 那么什么时候用第一种,什么时候用第二种呢?...使用第二种写法 var res *dao.BpCourseware 适用于定义一个指针变量,该变量需要在后续的代码中进行初始化,才能使用它进行赋值、参等操作。

20120
您找到你想要的搜索结果了吗?
是的
没有找到

Go基础系列:struct和嵌套struct

longshuai 23} 值 or 指针 Go函数给参数传递值的时候是以复制的方式进行的。...复制值时,如果函数的参数是一个struct对象,将直接复制整个数据结构的副本传递给函数,这有两个问题: 函数内部无法修改传递给函数的原始数据结构,它修改的只是原始数据结构拷贝后的副本 如果传递的原始数据结构很大...,完整地复制出一个副本开销并不小 所以,如果条件允许,应当给需要struct实例作为参数的函数struct的指针。...对于已经创建成功的struct实例p,如果这个实例是一个值而非指针(即p->{person_fields}),那么可以&p来获取这个已存在的实例的指针,然后传递给函数add(&p)。...对于尚未创建的struct实例,可以使用&person{}或者new(person)的方式直接生成实例的指针p,虽然是指针,但Go能自动解析成实例对象。然后将这个指针p传递给函数即可。

4.1K20

go语言中函数参数值还是引用的思考

TOC 背景 算起来这些年大大小小也用过一些不同编程语言,但平时开发还是以C++为主,得益于C++精确的语义控制,我可以在编写代码的时候精准地控制每一行代码的行为,以达到预期的目的。...C++函数参数的值和引用 熟悉C++的程序员们应该都清楚,C++里传递函数参数的时候,值还是引用是函数声明的时候决定的。...C++中形参指针也归类为值,因为这里形参copy的是一个指针的副本,本质上还是值,只不过和调用方的原始指针指向了同一块内存而已,所以函数内针对该内存进行的修改才会反应到外面,看起来像是“引用”,...go函数参数一律值 预声明类型int,string等,以及普通的命名结构类型没什么好说的,无论是传递该类型的值还是指针作为函数参数,本质上都是值,这点和C++一样。...C++的函数参数通过常引用和引用来区分入参和出参,对读代码的人来说一目了然;go函数参数不存在const修饰符,取而代之的提供了多返回值的特性,故完全可以把入参放到普通参数的位置,而把出参全部作为返回值

4.6K40

Golang中函数参存在引用传递吗?

继上篇文章后,继续来探讨下面的几个问题: 函数参中值传递、指针传递与引用传递到底有什么不一样? 为什么说 slice、map、channel 是引用类型?...文档地址:https://golang.org/ref/spec#Calls 官方文档已经明确说明:Go里边函数参只有值传递一种方式,为了加强自己的理解,再来把每种参方式进行一次梳理。...由于 Go 里边并不存在引用传递,我们常常看到说 Go 中的引用传递也是针对:Slice、Map、Channel 这几种类型(这是个错误观点),因此为了解释清楚引用传递,先劳烦大家看一段 C++ 的代码...如果go中存在引用传递,形参 s 的地址应该与实参 s1 一样(上面c++的证明),通过实际的情况我们发现它们具备完全不同的地址,也就是参依然发生了拷贝——值传递。...小结 Go函数参仅有值传递一种方式; slice、map、channel都是引用类型,但是跟c++的不同; slice能够通过函数参后,修改对应的数组值,是因为 slice 内部保存了引用数组的指针

2.2K20

C语言函数的栈帧详解

一个由系统自动分配的内存空间,譬如调用函数、创建临时变量时内存空间的创建与销毁。 用于存储函数内部的局部变量、方法调用、函数参数值等。 由高地址向低地址生长。...每调用一次函数便会创建一个独立栈帧。 栈帧中存放的是函数中的必要信息,局部变量、函数参、返回值等。 当函数运行完毕栈帧将会销毁。 ​ 下面进入主题,图解函数栈帧的创建与销毁过程。...在调试过程中将转到反汇编,便能直观的看到main函数栈帧创建的过程。首先需明确的是,函数栈帧由寄存器esp,ebp维护。...2.esp值传递给ebp。 3.esp减去0E4h:由于栈先使用高地址后使用低地址,减去一个值意味着esp指针向低地址移动了0E4h个地址,此处便开辟了main函数的栈帧。...eax,此时的ebp存放Add函数的栈底指针,(ebp + 8) 的位置即函数参时创建的ecx的地址,其内部存放的正是10。

2K20

Go 函数式编程篇(二):参数传递、变长参数与多返回值

上篇教程我们介绍了 Go 语言中函数的基本定义和调用,其中也涉及到了函数参和返回值,只不过那里演示的是最简单的场景,今天我们就更复杂的参和返回值进行介绍。...一、传递参数 按值Go 语言默认使用按值参来传递参数,也就是传递参数值的一个副本:函数接收到传递进来的参数后,会将参数值拷贝给声明该参数的变量(也叫形式参数,简称形参),如果在函数体中有对参数值做修改...(1, 2) = 8 引用参 如果你想要实现在函数中修改形参值可以同时修改实参值,需要通过引用参来完成,此时传递给函数的参数是一个指针,而指针代表的是实参的内存地址,修改指针引用的值即修改变量内存地址中存储的值...这里的按值参和引用参和前面指针使用入门中介绍的值拷贝和指针参是一个意思。...基本定义和值 接下来,我们来介绍下 Go 函数变长参数的用法。 很简单,只需要在参数类型前加上 ...

1.2K10

借问变量何处存,牧童笑称用指针,Go lang1.18入门精炼教程,由白丁入鸿儒,go lang类型指针(Pointer)的使用EP05

一种方法是将一个指向数组的指针递给方法: package main import ( "fmt" ) func modify(arr *[3]int) { (*arr)[0] = 90 }...,如果我们想通过一个函数改变一个数组的值,可以将该数组的切片当作参数传给函数,也可以将这个数组的指针当作参数传给函数,显而易见,使用切片更加方便。    ...结语     简而言之,很多编译型语言都在事实上存在指针c/c++是真实的指针,而Java中其实是指针的引用,可以理解为不能操作指针的值,不允许指针运算的指针。...文档地址:https://go.dev/ref/spec#Calls     一望而知,go lang的设计者们在go lang语法设计上存在“完美主义强迫症”,方法参是绝对的值,Go lang中方法参只有值传递一种方式...,不存在引用传递,这样一来,必须有明确的指针类型,才可以保证在值的前提下能对对象进行修改。

44340

C语言】指针进阶之值调用与址调用

1.前言 学习指针的⽬的是使⽤指针解决问题,那什么问题,⾮指针不可呢? ✔在编程语言C中,值调用和址调用是用来传递参数给函数的方法。...它们的主要区别在于参数传递的方式: ☞值调用:这是最基本的参数传递方式,它涉及将参数的值复制一份传递给函数。...在函数内部,对这些复制的值进行的任何修改都不会影响到原参数的值,因为函数只是在自己的局部范围内操作这个副本。 ☞址调用:这种方式则是将参数的地址传递给函数。...printf("交换前:a=%d b=%d\n", a, b);  Swap1(a, b);  printf("交换后:a=%d b=%d\n", a, b);  return 0; } 当我们运⾏代码...这种调⽤函数的⽅式我们之前在函数的时候就知道了,这种叫值调⽤。 结论:实参传递给形参的时候,形参会单独创建⼀份临时空间来接收实参,对形参的修改不影响实 参。 所以Swap是失败的了。 那怎么办呢?

9810

Golang数据类型之结构体-下篇

1、结构体指针 1.1 声明 1.2 声明并初始化 1.3 通过new函数创建指针对象 1.4 传递结构体指针 1.5 结构体值与结构体指针 1.6 值还是传递指针 2、匿名结构体 3、结构体方法...将一个结构体的指针递给函数,能否修改到该结构体 结果是可以修改该实例对象 func ChangeColor(car *Car) { car.Color = "blue" fmt.Println(...即什么时候值,什么时候传递指针?...传递值: 不希望实例被外部修改的时候,值就相当于copy了一份副本给函数 传递指针: 希望外部能修改到这个实例本身的时候,就需要传递该实例的指针,就是把该实例的内存地址告诉对方,可以通过地址直接找到本体...但是经常看到函数接收的结构体参数都是指针是为什么 因为复制值时,如果函数的参数是一个struct对象,将直接复制整个数据结构的副本传递给函数,这有两个问题 函数内部无法修改传递给函数的原始数据结构,

86020

C语言基础】:深入理解指针(二)

指针 - 指针C语言中,不止整数之间可以进行运算,其实指针指针之间也可以进行运算,指针指针之间可以进行减法运算,两个指针相减得到的是一个整数,表示它们之间相隔元素的个数。...函数里的x和y是一个独立的空间,在Swap函数内部进行了交换,但却无法返回到main函数中,导致a和b没有实现交换,Swap1函数在使用的时候,是把变量本身直接传递给函数,这种调用函数的方式我们之前在函数的时候就知道了...那么就可以使用指针了,在main函数中将a和b的地址传递给Swap函数,Swap函数里边通过地址间接的操作main函数中的a和b,并达到交换的效果就好了。...递给函数,这种函数调用方式叫:址调用。...址调用,可以让函数和主调函数之间建立真正的联系,在函数内部可以修改主调函数中的变量;所 以未来函数中只是需要主调函数中的变量值来实现计算,就可以采⽤值调用。

8610

tRPC-Go 链路透消息的源码级解读

概述在分布式链路追踪等场景下,会使用到微服务调用链路上的透能力,tRPC-Go 基于 tRPC 协议的头部设计实现了对链路透的支持,这篇文章从源码角度分析链路透的设计实现,文章中会涉及 tRPC-go...(ctx, req)这里的工厂函数和方法都是我们用 trpc create 命令生成的桩代码里提供的实现,下一小节我们会看到桩代码里的实现。...从 tRPC-go代码着手我们重点看看方法桩里边的代码:func (c *OrderClientProxyImpl) PlaceOrder(ctx context.Context, req *EmptyMessage...我们只想关注链路透传过程,所以我们后面重点关注 codec.WithCloneMessage 函数c.clientInvoke 方法的逻辑。...// 也就是说,将当前服务收到的链路透进一步传递给下一个服务 newMsg.clientMetaData = m.serverMetaData.Clone()// 一般需要拷贝消息的场景都是因为当前服务也需要

8810

Go Code Review Comments 译文(截止2018年7月27日)

持续更新中… 原文最新链接 https://github.com/golang/go/wiki/CodeReviewComments/5a40ba36d388ff1b8b2dd4c1c3fe820b8313152f...某些标准库函数 “strings” 包中的函数)会返回 in-band 错误值。这大大简化了字符串操作,代价是需要程序员做更多事。通常,Go 代码应返回表示错误的附加值。...此常见实例包括将指针递给 string(string)或是指向接口值(*io.Reader)的指针。在这两种情况下,值本身都是固定大小,可以直接传递。...如果接收器是大型结构或数组,则指针接收器更有效。多大才算大?假设它相当于将其包含的所有元素作为参数传递给方法。如果感觉太大,那么对接收器来说也太大了。...典型的 Go 失败测试: if got !

1.1K30

Go函数式编程和闭包

尽管Go不是一种典型的函数式编程语言,它却提供了一些函数式编程的特性,包括但不限于函数作为一等公民以及闭包。这篇文章将专注于这两个方面,并且通过代码示例进行解释。...下面的代码示例展示了如何在Go中将函数作为参数传递: package main import "fmt" // 定义一个接受两个整数和一个函数作为参数的函数 func compute(a int,...b int, operation func(int, int) int) int { return operation(a, b) } func main() { // 将一个匿名函数作为参数传递给...在main函数中,我们创建了一个匿名函数,并将其作为参数传递给compute函数。 闭包 闭包是函数式编程中的另一个重要概念。...这些特性使得Go在处理某些问题时,可以采用函数式编程的方法,提供代码的简洁性和表达力。在实际使用Go进行开发时,根据实际情况合理利用这些特性,可以使代码更加简洁、灵活和强大。

37920

深入分析golang多值返回以及闭包的实现

函数调用过程,参数是通过寄存器di和si(假设就两个参数)传递给被调用的函数,被调用函数的返回结果只能是通过eax寄存器返回给调用函数,因此C/C++函数只能返回一个值,那么我们是不是可以想象,golang...首先来看下test函数的汇编代码 ?...24,返回的第二个值存入fp+32,和我上述所说完全一致;golang函数调用过程,是通过fp+offset来实现参和返回值,而不像C/C++都是通过寄存器实现参和返回值; 但是,这里有个问题,我的变量都是...来看下test函数的汇编代码: ?...(SP),BX 很明显,main函数调用test函数获取的是闭包对象的地址,通过这个闭包对象地址找到闭包函数,然后执行这个闭包函数,并且把闭包对象的地址函数,这点和C++this指针原理一样,为了修改成员变量

2.5K60

Golang的逃逸分析和C以及Rust的此类问题的处理对比

Golang的逃逸分析 首先抛出几个常见的问题: 用golang编程时是选用指针还是值?既然指针效率高,那是不是只要不涉及复制需求的情况下每次都采用指针传递?...一般情况下指针传递效率是高于值传递。因为值会拷贝整个对象,而指针只会拷贝指针地址,指向的对象是同一个。指针可以减少值的拷贝。...总结下,在一般情况下,对于需要修改原对象值,或占用内存比较大的结构体,选择指针。对于只读的占用内存较小的结构体,直接值能够获得更好的性能。...云原生基础架构的中间层是golang开发的,云原生基础架构的底层,运行时,等等是rust开发,且越来越多的偏向底层组件,原来golang或c开发的正在被rust重写和代替。...总结下,云原生领域中,c和Rust负责底层部分,Go负责中间部分,共同服务上层各种语言的应用(java/go/ts/js)。

57220

为什么泛型会让你的Go程序变慢

平心而论,这两种担心可能被夸大了 另一方成面,泛型支持都认为,这是大规模复用代码,并能保持干净的功能 本篇文章不想在争论中战队,也没有建议如何在 go 中使用泛型。...,通常在堆上分配对象,然后将指针递给函数。...由于所有的对象都有相同的形状(它们都是指针!),我们对它们操作所需要的就是知道,这些方法在哪里。因此,传递给我们的通常伴随一个函数指针表,通常称为 虚拟方法表或是 vtable....这是迄今为止实泛型最简单的,同时对于编译器来讲也带来开销 历史上,单态化一直是在系统语言(C++、D或Rust)中实现泛型的首选设计。...这和我们希望的完全相反,即 de-virtualization 的同时,尽可能 inline 结束当前小节前,我们再看一下 go 栈逃逸的一个细节:单态函数 2 allocs/op, 因为进去的指针在栈

23730

【初识Go】| Day7 函数

值传递是指在函数调用过程中将实参拷贝一份到函数中,这样在函数中如果对参数进行修改,将不会影响到实参。...引用传递是指在函数调用过程中将实参的地址传递到函数中,那么在函数中对参数所进行的修改,将影响到实参。 如果想要函数可以直接修改参数的值,那么我们可以用指针传递,将变量的地址作为参数传递到函数中。...error) { return Fprintf(os.Stdout, format, a...) } 上面这段代码暂时看不懂也没关系,但是只需要记住,当你想传递给函数的参数不能确定有多少时可以使用变长参数...多返回值 go语言中函数还支持一个特性那就是:多返回值。...而且对于外部变量的操作是累加的,这与类中的静态变量也是一致的 在go语言学习笔记中,雨痕提到在汇编代码中,闭包返回的不仅仅是匿名函数,还包括所引用的环境变量指针,这与我们之前的解释也是类似的,闭包通过操作指针来调用对应的变量

30800
领券