我创建了一个界面,用于使用struct值进行基本数学运算。接口的数学函数总是更新结构指针的值。
我的问题是,在某些时候,我想将值覆盖到初始值,但我只有接口可以使用。因为它是一个指针界面(不是100%肯定,如果这是人们所说的),我无法克隆"结构的初始值,以便稍后覆盖。
请注意我尽量避免反思。
这是我的代码。可能比我试图解释它更有意义:
package main
import (
"fmt"
)
type mather interface {
add(mather) mather
sub(mather) mather
}
type float struct {
value float64
}
func (f *float) add(m mather) mather {
f.value += m.(*float).value
return f
}
func (f *float) sub(m mather) mather {
f.value -= m.(*float).value
return f
}
func (f *float) get() interface{} {
return *f
}
func main() {
var a, b, c mather
a = &float{2} // this could be any time. approximitly 10 possible types
b = &float{7} // this could be any time. approximitly 10 possible types
// float can't be used again below, only mather
c = a
fmt.Println(a)
fmt.Println(b)
fmt.Println()
// a's math
doMath(a)
// now math is done, we need to reset the value from before the math was done
// set *a equal to *c. (a == &float{2})
resetMath(a, c)
// b's math
doMath(b)
// now math is done, we need to reset the value from before the math was done
// set *b equal to *c. (b == &float{7})
resetMath(b, c)
fmt.Println(a)
fmt.Println(b)
}
func doMath(m mather) {
m.add(&float{3})
}
func resetMath(m mather, r mather) {
m = r
}
答案 0 :(得分:2)
您需要在clone
界面中定义set
和mather
方法,即:
type mather interface {
add(mather) mather
sub(mather) mather
get() interface{}
clone() mather
set(v mather)
}
get
类型中set
,clone
和float
的实现如下:
func (f *float) get() interface{} {
return f.value
}
func (f *float) clone() mather {
return &float{f.value}
}
func (f *float) set(v mather) {
switch v := v.(type) {
case *float:
f.value = v.value
//handle other possible types...
default:
//handle unknown types
}
}
见working example in Playground。唯一复杂的部分是set
,您应该在其中确定基础类型。在这里,您可以使用type switch
获取基础类型,然后将其分配给float
。需要在其他基础类型中添加类似的代码(您提到有10种可能的类型)。
答案 1 :(得分:1)
你可以使用简单的寻址操作符来实现它,如果你有一个基础类型的引用,你可以通过类型断言获得它,而不必诉诸于反射。获得*float
后,很容易:
f := &float{2}
var a, b *float
a = f
b = new(float)
*b = *f // Assign the value pointed to by f to the value pointed to by b
在这种情况下,您的本地变量现在是*float
而不是mather
,但至少在您的示例中无关紧要。如果它确实重要,如上所述,您可以使用类型断言。