Соответствие параметра типа функции в golang
package main
type gens func(args...interface{}) int
func sum1(a int,b int,c int) int {
return a+b+c
}
func sum2(a...interface{}) int {
ret := 0
for _,v := range a {
ret = ret + v.(int)
}
return ret
}
func main() {
var a gens
//a = sum1
a = sum2
println(a(1,2,3))
}
рассмотрите код выше, sum2 может работать, но sum1 нет.
компилятор сказал, что "нельзя использовать sum1 (тип func(int, int, int) int) в качестве типа gens при присваивании"
Причина, по которой я спрашиваю, потому что я хочу написать планировщик goroutine, который принимает функции переменных-параметров, Как я могу сделать, но переписать множество других функциональных параметров в "args...interface{}"
Спасибо!
3 ответа
type gens func(args...interface{}) int
Вы делаете тип gens, который является функцией, имеющей аргументы в формате интерфейса.
sum1 не принимает интерфейс в качестве входных данных, поэтому выдает ошибку
package main
type gens func(args...interface{}) int
func sum1(a...int) int {
ret := 0
for _,v := range a {
ret = ret + v
}
return ret
}
func sum2(a...interface{}) int {
ret := 0
for _,v := range a {
if _,ok := v.(int);ok {
ret = ret + v.(int)
}
}
return ret
}
func main() {
var a gens
println(sum2(1,'2',3))
//a = sum1
a = sum2
println(a(1,2,3))
}
я изменяю код следующим образом. просто лучший способ показать, как я думаю и учусь, извините мой бассейн английский T_T
в функции sum2 аргументы принимают фактически фрагмент интерфейса, вы можете передать строку любого типа, int и т. д., см. выше, я передаю 1,'2',3 - теперь все нормально.
но в "типе функции", который точно и однозначно определить тип нельзя. я не могу запустить компилятор = sum1, скажем "не могу использовать sum1 (тип func(...int) int) как тип gens в присваивании"
в структуре данных golang интерфейс {} определен не так, как другие, я думаю, что определение типа будет проверяться более строго! я нахожу ответ на http://golang.org/doc/faq#How_do_I_get_dynamic_dispatch_of_methods
Ваши функции sum1
а также sum2
имеют разные подписи и поэтому sum1 не может быть назначен типу gens
По возможности вам следует избегать использования interface{}
Тип данных, так как он требует преобразования типов во время выполнения, когда вы работаете с ним. (конечно, есть веские причины для этого, например, демаршалинг и т. д.)
Вы можете прочитать больше о пустом интерфейсе здесь: http://jordanorelli.com/post/32665860244/how-to-use-interfaces-in-go
Вы можете реализовать переключатель типов в sum2 для обработки различных примитивных типов, а затем добавить их:
func sum2(a...interface{}) int {
ret := 0
for _,v := range a {
switch d := v.(type) {
case int, int32, int16:
ret += int(d)
case float64,float32:
ret += float(d)
}
if _,ok := v.(int);ok {
ret = ret + v.(int)
}
}
return ret
}
Или вы можете сами определить интерфейс, который затем принимаете в функции, подобной этой
type Integer interface{
Int() int
}
func sum(i... Integer) {
result := 0
for _, v := range i {
result += v.Int()
}
}
type myfloat float64
func (m myfloat) Int() int {
return int(m)
}
Что касается вашего варианта использования, будет рекомендован последний способ. Дайте каждой задаче такое поведение, как "run()", и тогда планировщик знает, что с ней делать.