英文:
Is it possible to write a constraint to exclude a type?
问题
type NonString interface {
// ???
}
func MyFunc[T NonString](v T) T {
return v
}
func main() {
MyFunc(1) // OK
MyFunc(false) // OK
MyFunc([]string{}) // OK
MyFunc("hi, boy!") // 我希望在这里发生编译错误!
}
上述代码中的注释描述了我想要的情况。
在 Golang 中是否可能实现这个要求?
原始场景
我有两个函数如下:
func Any2String(v any) string {
return fmt.Sprint(v) // 慢速版本
}
func Integer2String[N Integer](v N) string {
return strconv.FormatInt(int64(v), 10) // 快速版本
}
Any2String(v)
可以将任何 v
转换为字符串。然而,如果 v
是整数,Integer2String(v)
的速度要快得多。
因此,我希望编译器在适用更快的 Integer2String(v)
的情况下,阻止我调用 Any2String(v)
。
英文:
type NonString interface {
// ???
}
func MyFunc[T NonString](v T) T {
return v
}
func main() {
MyFunc(1) // OK
MyFunc(false) // OK
MyFunc([]string{}) // OK
MyFunc("hi, boy!") // I hope a comiler error occurs here!
}
What I want is decribed in the comments of the code above.
Is it possible in golang?
Original Scenario
I have two functions as follows:
func Any2String(v any) string {
return fmt.Sprint(v) // Slow version
}
func Integer2String[N Integer](v N) string {
return strconv.FormatInt(int64(v), 10) // Fast version
}
Any2String(v)
can convert any v
to a string. However, if v
is an integer, Integer2String(v)
is much more faster.
So, I want the compiler to PREVENT me from calling Any2String(v)
when the faster Integer2String(v)
is applicable.
答案1
得分: 1
不,这是不可能的。约束类型集不能表示为集合的减法。
可以定义无法满足任何类型的约束,例如:
type NotSatisfiable interface {
int
foo()
}
这个约束要求一个类型完全是int
类型,并且有一个名为foo()
的方法。由于无法在预声明的类型上定义方法,因此无法满足这个约束。
然而,你不能定义像"any-minus-int"或"any-plus-NotSatisfiable"这样的约束。
如果你有一个函数对除了少数几种类型之外的任何类型都能正常工作,只需使用类型切换:
func ToString(v any) string {
switch t := v.(type) {
case int:
return Integer2String(t)
default:
return Any2String(t)
}
}
你甚至不需要泛型,因为类型为any
的普通参数完全可以胜任。
英文:
No, it's not possible. Constraint type sets cannot be expressed as set subtraction.
It is possible to define constraints that can't be satisfied by any type, for example:
type NotSatisfiable interface {
int
foo()
}
This constraint mandates a type that is exactly int
and that has a method foo()
. Since you can't define methods on predeclared types, it's not possible to satisfy this constraint.
However you can't define a constraint like "any-minus-int" or "any-plus-NotSatisfiable".
If you have a function that works exactly the same for any type except a discrete number of types, just use a type switch:
func ToString(v any) string {
switch t := v.(type) {
case int:
return Integer2String(t)
default:
return Any2String(t)
}
}
You don't even need generics, because a regular argument of type any
works just fine.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论