我今天学到的:通过引用传递Golang中的接口参数

通过Golang中的引用传递参数有关我所学到的关于Golang中通过引用传递引用的简单知识的简单日记通过基于Golang中的接口参数引用传递

回到大学时代,我记得有两种方法可以将参数传递给函数。 一个通过值传递,另一个通过引用传递。 这两种方式都有不同的概念,有时会给程序员带来混乱。

简单来说,按值传递就是当我们传递参数而没有指向该值的原始地址的指针时。 通过引用传递是在传递带有给定参数的指针的参数时。

在Golang中,我们可以在下面的示例中看到这两个。

<code class = "language-markup" >func pass ByValue( item < strong > string < / strong >) {}
func pass ByReference( item < strong > * string < / strong >) {}</code>

在Golang中按引用传递和按值传递

实际上,已经有许多关于如何在Golang中通过引用传递和通过Golang传递值的示例,我们可以在Internet上找到它们。

所以在这里,我将举一个简单的例子。

< code class = "language-markup" >package main</ code >
< code class = "language-markup" > import (
 "fmt"
)</ code >
<code class = "language-markup" >func main() {
 item := ""
 passByValue( item )
 fmt.Println( item )
 passByReference(&amp; item )
 fmt.Println( item )
}</code>
< code class= "language-markup" >func passByValue( item  string)  {
 item  = "hello"
}</ code >
< code class= "language-markup" >func passByReference( item  * string)  {
 * item  = "world"
}</ code >

上面的示例显示了一种典型的方式,我们可以根据参数的类型(通过引用或值)传递参数。

在Golang中的接口参数上按引用传递

但是,有一天。 我遇到了需要解决的有关通过引用传递参数的问题。 不像我以前做过的任何普通人,这是使用参数接口的。 因此,基本上,此函数接受interface {}中的所有内容,并根据该函数内部发生的逻辑填充值。

该函数如下所示。

<code class = "language-markup" >func do SomethinWithThisParam( item interface {}) {}</code>

这个函数很简单,它只接受一个接口,并在其中做一些事情。 它不会返回任何错误,因此它只是将其中带有值的项目水合。

因此,为了解决这种奇怪的行为,我尝试自己尝试解决。 在下面,我将说明如何解决该问题的步骤。

第一次尝试:指向接口的指针[不起作用]

刚开始,我试着喜欢非接口{}。 我在界面中放置了一个指针。 但这是行不通的。

< code class = "language-markup" >package main</ code >
< code class = "language-markup" > import (
 "fmt"
)</ code >
<code class = "language-markup" >func main () {
 var item Student
 do SomethinWithThisParam(& amp ; item )
 fmt. Printf( "%+v" , item )
}</code>
< code class= "language-markup" > type Student struct {
 ID   string
 Name string
}</ code >
<code class = "language-markup" >func do SomethinWithThisParam( item * interface {}) {
 *item = &amp;Student{
  ID:   "124" ,
  Name: "Iman Tumorang" ,
 }
}</code>

这个无法编译,会引发错误。

<code class =" language - markup "> cannot use & amp ; item  (type *Student) as type * interface  {} in argument to doSomethinWithThisParam:
	* interface  {} is pointer to interface , not interface < /code >

第二次尝试:直接为接口分配值[无效]

第二个,我尝试不使用指向接口的指针,而是直接将值分配给给定的参数。

<code class = "language-markup" >func do SomethinWithThisParam( item interface {}) {
 item = &amp;Student{
  ID:   "124" ,
  Name: "Iman Tumorang" ,
 }
}</code>
< code class = "language-markup" > // Print: {ID: Name:}</code>

并且在打印数据后,它仍然无法正常工作。 打印空白值。

第三次尝试:强制转换为原始类型并分配值[有效但…。]

后来,在尝试了许多东西之后,我发现了一个可行的东西。 该参数仍然是interface {},但不是直接分配值,而是首先将其强制转换回原始类型。 目前,这有点棘手。 我们必须小心如何使用它。 请参见下面的区别。

不起作用:
下面的这个例子不起作用。

< code class= "language-markup" >func doSomethinWithThisParam( item  interface{}) {
 origin := item.(*Student)
 origin = &amp ;Student{
  ID:   "124" ,
  Name: "Iman Tumorang" ,
 }
 item  = origin
}</ code >
< code class = "language-markup" > // Print: {ID: Name:}</code>

工作时间:
但这是可行的。

< code class= "language-markup" >func doSomethinWithThisParam(item interface{}) {
 origin := item.(*Student)
 origin .Name = "Iman Tumorang"
 origin .ID = "124"
}</code>
< code class = "language-markup" > // Print: {ID:124 Name:Iman Tumorang}</code>

认真吗????? 😱
起初,我有点困惑。 这里到底发生了什么? 当我做这样的事情怎么可能不起作用。

<code class="language-markup"> origin := item.(*Student)
 origin = &amp ;Student{
  ID:   "124" ,
  Name: "Iman Tumorang" ,
 } </code>

但是有了这个,它就起作用了。

< code class= "language-markup" >origin := item.(*Student)
origin .Name = "Iman Tumorang" </code>

需要几分钟来解决这个问题。 但是后来我明白了为什么会这样。

另一个

解决问题后,我意识到了一些事情。 第一个失败,因为它替换了地址。 因此,我尝试使用一种仅更改值的新方法来代替地址。

< code class= "language-markup" >func doSomethinWithThisParam( item  interface{}) {
 origin := item.(*Student)
 < strong>*origin</strong>  = Student{
  ID:   "124" ,
  Name: "Iman Tumorang" ,
 }
 item  = origin
}</ code >
< code class = "language-markup" > // Print: {ID:124 Name:Iman Tumorang}</code>

这个很好用。 这使我意识到,当我们想要更改指针变量中的值时,我们需要直接设置为该值,而不是自行更改其地址。

最终解析器

因此,在尝试了许多试验之后,最终我选择了最后一个。 并且由于我正在使用的此函数将根据当前任务有点通用,因此我对其进行了转换并添加了开关盒条件,因此根据我制作的开关盒将更加通用。

简单来说,我在当前任务上所做的所有工作都可以在下面的示例中进行描述。 有一个通用函数可以接受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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值