我正在尝试学习接口以及如何编写单个函数来处理不同类型的函数。我想出了这个例子,我在int
切片或float32
切片中找到了最大值。代码如下。我一直得到这个错误“t不是一个类型”。有人可以告诉我出了什么问题以及如何修复它吗?
package main
import "fmt"
import "reflect"
var _ = fmt.Println
var _ = reflect.TypeOf
func maxer(s interface{}) interface{} {
v := reflect.ValueOf(s)
t := v.Type()
maxval := s.(t)[0]
for _, v := range s.(t)[1:] {
if v > maxval {
maxval = v
}
}
return maxval
}
func main() {
fmt.Println(maxer([]int{1, 2, 3, 4}))
fmt.Println(maxer([]float32{1.1, 2.1, 3.14, 0.1, 2.4}))
答案 0 :(得分:1)
我认为在这种情况下你最终需要手动处理不同的类型。 AFAIK,类型断言在编译时必须是实数类型。这是我最好的尝试:http://play.golang.org/p/J8RdHF2MVV
答案 1 :(得分:1)
我正在尝试学习接口以及如何编写单个函数来处理不同类型的函数。
然后避免整个反射包可能更简单,只需为您的特定目的定义一个接口..以及实现您的接口的类型。像这样的东西:
package main
import "fmt"
import "math"
// Homegrown types
type IntArray []int
type Float32Array []float32
// Max defined for type IntArray
func (a IntArray) Max() float64 {
max := math.MinInt32;
for i := 0; i < len(a); i++ {
if a[i] > max {
max = a[i]
}
}
return float64(max)
}
// Max defined for type Float32Array
func (a Float32Array) Max() float64 {
max := float32(-1 * math.MaxFloat32)
for i := 0; i < len(a); i++ {
if a[i] > max {
max = a[i]
}
}
return float64(max)
}
// Define an interface that works for any type
// containing a Max function returning a float64
type Maxing interface {
Max() float64
}
// Define a function that works with your interface type
func maxer(m Maxing) float64 {
return m.Max();
}
func main(){
// Declare a new IntArray
i := IntArray([]int{1,2,3})
// Declare a new Float32Array
f := Float32Array([]float32{1.0,2.0,3.0})
// Use any type implementing the Max interface with the 'maxer' func
fmt.Printf("maxer(IntArray) = %f\n", maxer(i));
fmt.Printf("maxer(Float32Array) = %f\n", maxer(f));
}
答案 2 :(得分:0)
与bjarneh's response相似。如果你想通过接口这样做,最好避免反映。反射不适合比较值,因为您无法知道值的类型。
我的建议是实现与go's sort interface类似的东西,允许你在任何类型上使用函数sort。
以这种方式实现它将允许您获得结构或字符串的最大值,只要您为它们实现了这些函数。
package main
import (
"fmt"
)
type Comparable interface {
Less(i, j int) bool
Len() int
Val(i int) interface{}
}
func maxer(s Comparable) (interface{}) {
if s.Len() == 0 {
return nil
}
maxI := 0
for i := 1; i < s.Len(); i++ {
if s.Less(maxI, i) {
maxI = i
}
}
return s.Val(maxI)
}
type MaxerInt []int
func (m MaxerInt) Len() int {return len(m)}
func (m MaxerInt) Val(i int) interface{} {return m[i]}
func (m MaxerInt) Less(i, j int) bool {return m[i] < m[j]}
type MaxerFloat []float64
func (m MaxerFloat) Len() int {return len(m)}
func (m MaxerFloat) Val(i int) interface{} {return m[i]}
func (m MaxerFloat) Less(i, j int) bool {return m[i] < m[j]}
func main() {
fmt.Println(maxer(MaxerInt{1, 2, 3, 4}))
fmt.Println(maxer(MaxerFloat{1.1, 2.1, 3.14, 0.1, 2.4}))
}