Соответствие параметра типа функции в 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()", и тогда планировщик знает, что с ней делать.

Другие вопросы по тегам