基本类型在Go中实现了哪些接口?

huangapple go评论71阅读模式
英文:

What interfaces do basic types in go implement

问题

你能用接口来捕获“支持+、-、*和/的类型”吗?或者如果你想在所有数字类型上创建一个函数,你只能使用类型切换吗?

英文:

Can you capture "a type that supports +, - * and /" with an interface? Or do you just have to use a typeswitch if you want to make a function on all number types?

答案1

得分: 3

接口定义了一个类型实现的一组方法。在Go中,基本类型没有方法。它们唯一满足的接口是空接口interface{}

如果你希望处理所有数字类型,你可以使用反射和类型切换的组合。如果只使用类型切换,代码会更多,但速度应该更快。如果使用反射,速度会慢一些,但需要的代码更少。

请记住,在Go中,很常见的情况是你不需要让一个函数适用于所有数值类型。这很少是必要的。

类型切换示例:

func square(num interface{}) interface{} {
    switch x := num.(type) {
    case int:
        return x*x
    case uint:
        return x*x
    case float32:
        return x*x
    // 还有很多其他数值类型要列举
    default:
        panic("square(): 不支持的类型 " + reflect.TypeOf(num).Name())
    }
}

反射 + 类型切换示例:

func square(num interface{}) interface{} {
    v := reflect.ValueOf(num)
    ret := reflect.Indirect(reflect.New(v.Type()))

    switch v.Type().Kind() {
    case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
        x := v.Int()
        ret.SetInt(x * x)
    case reflect.Uint, reflect.Uintptr, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
        x := v.Uint()
        ret.SetUint(x * x)
    case reflect.Float32, reflect.Float64:
        x := v.Float()
        ret.SetFloat(x * x)
    default:
        panic("square(): 不支持的类型 " + v.Type().Name())
    }

    return ret.Interface()
}
英文:

An interface defines a set of methods a type implements. In Go, basic types have no methods. The only interface they satisfy is the empty interface, interface{}.

If you wish to work on all number types, you can use a combination of reflect and type switches. If you use only type switches, you will have more code but it should be faster. If you use reflect, it will be slow but require much less code.

Please remember that in Go, it is very common that you don't attempt to make a function work on all numeric types. It is rarely necessary.

Type Switch Example:

func square(num interface{}) interface{} {
    switch x := num.(type) {
    case int:
        return x*x
    case uint:
        return x*x
    case float32:
        return x*x
    // many more numeric types to enumerate
    default:
        panic("square(): unsupported type " + reflect.TypeOf(num).Name())
    }
}

Reflect + Typeswitch Example:

func square(num interface{}) interface{} {
	v := reflect.ValueOf(num)
	ret := reflect.Indirect(reflect.New(v.Type()))

	switch v.Type().Kind() {
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		x := v.Int()
		ret.SetInt(x * x)
	case reflect.Uint, reflect.Uintptr, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		x := v.Uint()
		ret.SetUint(x * x)
	case reflect.Float32, reflect.Float64:
		x := v.Float()
		ret.SetFloat(x * x)
	default:
		panic("square(): unsupported type " + v.Type().Name())
	}

	return ret.Interface()
}

答案2

得分: 1

预声明类型没有附加的方法。

算术运算符可以声明为某个接口的方法集,但只能作为例如方法'Add','Sub'等,即无法重新定义多态的'+','-'等运算符的功能。

英文:

Predeclared types have no methods attached.

Arithmetic operators can be declared as a method set of some interface, but only as eg. methods 'Add', 'Sub' etc., ie. there's no way to redefine what the polymorphic '+', '-', ... operators do.

huangapple
  • 本文由 发表于 2012年12月26日 22:37:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/14042072.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定