Golang:交换两个数字的接口

Golang:交换两个数字的接口,第1张

Golang:交换两个数字的接口

首先,

interface{}
类型只是接受所有值的类型,因为它是带有空方法集的接口,并且每种类型都可以满足该要求。
int
例如没有任何方法,也没有
interface{}

对于交换两个变量的值的方法,首先需要确保这些变量实际上是可修改的。传递给函数的值始终会被复制(切片和映射之类的引用类型除外,但这不是我们当前关注的问题)。您可以通过使用指向变量的指针来实现可修改的参数。

因此,有了这些知识,您就可以

SwapNum
像下面这样定义:

func SwapNum(a interface{}, b interface{})

现在

SwapNum
是一个接受两个任何类型参数的函数。你不会写

func SwapNum(a *interface{}, b *interface{})

因为这将只接受类型的参数,

*interface{}
而不是任何类型的参数。(在这里自己尝试)。

因此,我们有一个签名,剩下的唯一事情就是交换值。

func SwapNum(a interface{}, b interface{}) {    *a, *b = *b, *a}

不,这将 无法
正常工作。通过使用,

interface{}
我们必须执行运行时类型声明来检查我们是否在做正确的事情。因此,必须使用该
reflect
软件包扩展代码。如果您不了解反射,本文可能会让您入门。

基本上,我们将需要以下功能:

func SwapNum(a interface{}, b interface{}) {    ra := reflect.ValueOf(a).Elem()    rb := reflect.ValueOf(b).Elem()    tmp := ra.Interface()    ra.Set(rb)    rb.Set(reflect.ValueOf(tmp))}

该代码反映

a
b
使用
reflect.ValueOf()
了我们可以对其进行检查的代码。在同一行中,我们假设我们有指针值并通过调用它们来取消引用
.Elem()
它们。

这基本上转化为

ra := *a
rb :=*b
。之后,我们
*a
通过使用
.Interface()

并分配值(有效地制作副本)来请求的副本。

最后,我们使用] 5设置

a
to 的值,该值转换为
然后分配给,我们将其存储在temp中。变量之前。为此,我们需要转换回自身的反射,以便可以使用它(将a
作为参数)。
b``[ra.Set(rb)
*a =*b``b``a``tmp``rb.Set()``reflect.Value

我们可以做得更好吗?

是!
我们可以使用来使代码更安全,或者更好地使

Swap
类型的定义安全
reflect.MakeFunc
。在文档中(跟随链接)是一个示例,非常类似于您尝试的示例。本质上,您可以使用反射将内容填充到函数原型中。当您提供函数的原型(签名)时,编译器可以检查类型,将值减小为时无法检查类型
interface{}

用法示例:

var intSwap func(*int, *int)a,b := 1, 0makeSwap(&intSwap)intSwap(&a, &b)// a is now 0, b is now 1

其背后的代码:

swap := func(in []reflect.Value) []reflect.Value {    ra := in[0].Elem()    rb := in[1].Elem()    tmp := ra.Interface()    ra.Set(rb)    rb.Set(reflect.ValueOf(tmp))    return nil}makeSwap := func(fptr interface{}) {    fn := reflect.ValueOf(fptr).Elem()    v := reflect.MakeFunc(fn.Type(), swap)    fn.Set(v)}

的代码与的代码

swap
基本相同
SwapNum
makeSwap
与文档中使用的相同,说明得很好。

免责声明:
上面的代码对给定的值和值的外观进行了许多假设。通常,例如,您需要检查给定的值

SwapNum
实际上是指针值,依此类推。为了清楚起见,我将其省略。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5013010.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-14
下一篇 2022-11-15

发表评论

登录后才能评论

评论列表(0条)

保存