通过Golang中的引用传递参数有关我所学到的关于Golang中通过引用传递引用的简单知识的简单日记通过基于Golang中的接口参数引用传递
回到大学时代,我记得有两种方法可以将参数传递给函数。 一个通过值传递,另一个通过引用传递。 这两种方式都有不同的概念,有时会给程序员带来混乱。
简单来说,按值传递就是当我们传递参数而没有指向该值的原始地址的指针时。 通过引用传递是在传递带有给定参数的指针的参数时。
在Golang中,我们可以在下面的示例中看到这两个。
class = "language-markup" >func pass ByValue( item < strong > string < / strong >) {}
func pass ByReference( item < strong > * string < / strong >) {}
在Golang中按引用传递和按值传递
实际上,已经有许多关于如何在Golang中通过引用传递和通过Golang传递值的示例,我们可以在Internet上找到它们。
所以在这里,我将举一个简单的例子。
< code class = "language-markup" >package maincode >
< code class = "language-markup" > import (
"fmt"
)code >
class = "language-markup" >func main() {
item := ""
passByValue( item )
fmt.Println( item )
passByReference(& item )
fmt.Println( item )
}
< code class= "language-markup" >func passByValue( item string) {
item = "hello"
}code >
< code class= "language-markup" >func passByReference( item * string) {
* item = "world"
}code >
上面的示例显示了一种典型的方式,我们可以根据参数的类型(通过引用或值)传递参数。
但是,有一天。 我遇到了需要解决的有关通过引用传递参数的问题。 不像我以前做过的任何普通人,这是使用参数接口的。 因此,基本上,此函数接受interface {}中的所有内容,并根据该函数内部发生的逻辑填充值。
该函数如下所示。
class = "language-markup" >func do SomethinWithThisParam( item interface {}) {}
这个函数很简单,它只接受一个接口,并在其中做一些事情。 它不会返回任何错误,因此它只是将其中带有值的项目水合。
因此,为了解决这种奇怪的行为,我尝试自己尝试解决。 在下面,我将说明如何解决该问题的步骤。
刚开始,我试着喜欢非接口{}。 我在界面中放置了一个指针。 但这是行不通的。
< code class = "language-markup" >package maincode >
< code class = "language-markup" > import (
"fmt"
)code >
class = "language-markup" >func main () {
var item Student
do SomethinWithThisParam(& amp ; item )
fmt. Printf( "%+v" , item )
}
< code class= "language-markup" > type Student struct {
ID string
Name string
}code >
class = "language-markup" >func do SomethinWithThisParam( item * interface {}) {
*item = &Student{
ID: "124" ,
Name: "Iman Tumorang" ,
}
}
这个无法编译,会引发错误。
class =" language - markup "> cannot use & amp ; item (type *Student) as type * interface {} in argument to doSomethinWithThisParam:
* interface {} is pointer to interface , not interface < /code >
第二次尝试:直接为接口分配值[无效]
第二个,我尝试不使用指向接口的指针,而是直接将值分配给给定的参数。
class = "language-markup" >func do SomethinWithThisParam( item interface {}) {
item = &Student{
ID: "124" ,
Name: "Iman Tumorang" ,
}
}
< code class = "language-markup" > // Print: {ID: Name:}
并且在打印数据后,它仍然无法正常工作。 打印空白值。
第三次尝试:强制转换为原始类型并分配值[有效但…。]
后来,在尝试了许多东西之后,我发现了一个可行的东西。 该参数仍然是interface {},但不是直接分配值,而是首先将其强制转换回原始类型。 目前,这有点棘手。 我们必须小心如何使用它。 请参见下面的区别。
不起作用:
下面的这个例子不起作用。
< code class= "language-markup" >func doSomethinWithThisParam( item interface{}) {
origin := item.(*Student)
origin = & ;Student{
ID: "124" ,
Name: "Iman Tumorang" ,
}
item = origin
}code >
< code class = "language-markup" > // Print: {ID: Name:}
工作时间:
但这是可行的。
< code class= "language-markup" >func doSomethinWithThisParam(item interface{}) {
origin := item.(*Student)
origin .Name = "Iman Tumorang"
origin .ID = "124"
}
< code class = "language-markup" > // Print: {ID:124 Name:Iman Tumorang}
认真吗?????
起初,我有点困惑。 这里到底发生了什么? 当我做这样的事情怎么可能不起作用。
origin := item.(*Student)
origin = & ;Student{
ID: "124" ,
Name: "Iman Tumorang" ,
}
但是有了这个,它就起作用了。
< code class= "language-markup" >origin := item.(*Student)
origin .Name = "Iman Tumorang"
需要几分钟来解决这个问题。 但是后来我明白了为什么会这样。
解决问题后,我意识到了一些事情。 第一个失败,因为它替换了地址。 因此,我尝试使用一种仅更改值的新方法来代替地址。
< code class= "language-markup" >func doSomethinWithThisParam( item interface{}) {
origin := item.(*Student)
< strong>*origin = Student{
ID: "124" ,
Name: "Iman Tumorang" ,
}
item = origin
}code >
< code class = "language-markup" > // Print: {ID:124 Name:Iman Tumorang}
这个很好用。 这使我意识到,当我们想要更改指针变量中的值时,我们需要直接设置为该值,而不是自行更改其地址。
因此,在尝试了许多试验之后,最终我选择了最后一个。 并且由于我正在使用的此函数将根据当前任务有点通用,因此我对其进行了转换并添加了开关盒条件,因此根据我制作的开关盒将更加通用。
简单来说,我在当前任务上所做的所有工作都可以在下面的示例中进行描述。 有一个通用函数可以接受interface {}并在其中执行某些操作。 它支持许多结构。
代码段如下所示:
package main
import (
"fmt"
)
func main () {
var item Student
doSomethinWithThisParam(&item)
fmt.Printf( "%+v" , item)
}
type Student struct {
ID string
Name string
}
func doSomethinWithThisParam (item interface {}) {
switch v := item.( type ) {
case *Student:
*v = Student{
ID: "124" ,
Name: "Iman Tumorang" ,
}
// another case
}
}
在Golang中,这确实是一件严肃的事情。 在使用传递引用和接口{}时,我们必须非常小心。 为避免任何不必要的错误,我建议向使用引用传递方法的每个函数添加单元测试。
老实说,我在这个问题上停留了一个小时。 因此,如果您认为这是一件好事,请与我们分享这篇文章,这样任何人都不会遇到同样的问题。
From: https://hackernoon.com/today-i-learned-pass-by-reference-on-interface-parameter-in-golang-35ee8d8a848e