调用泛型函数类型:无效操作:不能调用非函数 fn
Calling a generic function type: invalid operation: cannot call non-function fn
我将 post 我目前正在处理的代码示例。我收到错误:
error: invalid operation: cannot call non-function fn (variable of type MF constrained by MapFunc)
是否可以使用包含不同函数签名的约束以这种方式使用? (如果可能的话,我想了解如何让我写的东西首先发挥作用。)
示例如下:
package main
import "fmt"
// MapFunc constraint used in Funcy
type MapFunc interface {
func(s string, ss []string) []string | func(s string, ss []string) []bool
}
// MapFuncType used for Funcy return constraint
type MapFuncType interface {
string | bool
}
// Funcy preforms map operation on generic map functions
func Funcy[MF MapFunc, MFT MapFuncType](s string, ss []string, fn MF) []MFT {
return fn(s, ss)
// error: invalid operation: cannot call non-function fn (variable of type
// MF constrained by MapFunc)
}
// appendTo adds given string to the end of each index of given slice of strings
// Ex. appendTo("_", []string{"append", "to"}) --> []string{"append_", "to_"}
func appendTo(s string, ss []string) []string {
var slice []string
for _, v := range ss {
slice = append(slice, v+s)
}
return slice
}
// isMatch checks given string against each index in given string slice for a
// match
// Ex. isMatch("hi", []string{"hello", "hi"}) --> []bool{false, true}
func isMatch(s string, ss []string) []bool {
var slice []bool
for _, v := range ss {
slice = append(slice, s == v)
}
return slice
}
func main() {
slice1 := []string{"append", "to"}
slice2 := []string{"hello", "hi"}
fmt.Println(Funcy(slice1, appendTo))
// want: []string{"append_", "to_"}
// got: error: cannot infer MFT
fmt.Println(Funcy(slice2, isMatch))
//[]bool{false, true}
// got: error: cannot infer MFT
}
当您将类型参数 MF
约束为 MapFunc
时,您无法调用 fn
,因为 MapFunc
的类型集中的函数类型不有相同的签名。他们有不同的 return 类型 []string
和 []bool
.
所以 fn
类型的变量实际上不支持被调用,你会得到(有点神秘的)错误消息“无法调用 non-function fn”。
更正式地说,只有 具有核心类型 类型函数的值才能被调用,但约束 MapFunc
没有核心类型。
解决方法是参数化 MapFunc
并将该类型参数用作 return 值,这样在实例化时,它就会有一个核心类型:
type MapFunc[T MapFuncType] interface {
func(s string, ss []string) []T
}
并在Funcy
中用MFT
实例化约束:
func Funcy[MF MapFunc[MFT], MFT MapFuncType](s string, ss []string, fn MF) []MFT {
return fn(s, ss)
}
我将 post 我目前正在处理的代码示例。我收到错误:
error: invalid operation: cannot call non-function fn (variable of type MF constrained by MapFunc)
是否可以使用包含不同函数签名的约束以这种方式使用? (如果可能的话,我想了解如何让我写的东西首先发挥作用。)
示例如下:
package main
import "fmt"
// MapFunc constraint used in Funcy
type MapFunc interface {
func(s string, ss []string) []string | func(s string, ss []string) []bool
}
// MapFuncType used for Funcy return constraint
type MapFuncType interface {
string | bool
}
// Funcy preforms map operation on generic map functions
func Funcy[MF MapFunc, MFT MapFuncType](s string, ss []string, fn MF) []MFT {
return fn(s, ss)
// error: invalid operation: cannot call non-function fn (variable of type
// MF constrained by MapFunc)
}
// appendTo adds given string to the end of each index of given slice of strings
// Ex. appendTo("_", []string{"append", "to"}) --> []string{"append_", "to_"}
func appendTo(s string, ss []string) []string {
var slice []string
for _, v := range ss {
slice = append(slice, v+s)
}
return slice
}
// isMatch checks given string against each index in given string slice for a
// match
// Ex. isMatch("hi", []string{"hello", "hi"}) --> []bool{false, true}
func isMatch(s string, ss []string) []bool {
var slice []bool
for _, v := range ss {
slice = append(slice, s == v)
}
return slice
}
func main() {
slice1 := []string{"append", "to"}
slice2 := []string{"hello", "hi"}
fmt.Println(Funcy(slice1, appendTo))
// want: []string{"append_", "to_"}
// got: error: cannot infer MFT
fmt.Println(Funcy(slice2, isMatch))
//[]bool{false, true}
// got: error: cannot infer MFT
}
当您将类型参数 MF
约束为 MapFunc
时,您无法调用 fn
,因为 MapFunc
的类型集中的函数类型不有相同的签名。他们有不同的 return 类型 []string
和 []bool
.
所以 fn
类型的变量实际上不支持被调用,你会得到(有点神秘的)错误消息“无法调用 non-function fn”。
更正式地说,只有 具有核心类型 类型函数的值才能被调用,但约束 MapFunc
没有核心类型。
解决方法是参数化 MapFunc
并将该类型参数用作 return 值,这样在实例化时,它就会有一个核心类型:
type MapFunc[T MapFuncType] interface {
func(s string, ss []string) []T
}
并在Funcy
中用MFT
实例化约束:
func Funcy[MF MapFunc[MFT], MFT MapFuncType](s string, ss []string, fn MF) []MFT {
return fn(s, ss)
}