Как использовать операторы Infix (Сравнение) в качестве параметров в Go - PullRequest
0 голосов
/ 31 августа 2018

В GoLang можно использовать функции в качестве параметров, например, в этом простом примере, который сравнивает два числа на основе либо меньшего или равного (<=), либо большего или равного оператору (>= )

package main

func leq(x, y int) bool {
    return x <= y
}

func geq(x, y int) bool {
    return x >= y
}

func compare(x, y int, comparator func(int, int) bool) bool {
    return comparator(x, y)
}

func main() {
    println(compare(3, 5, leq)) //true
    println(compare(5, 3, leq)) //false
    println(compare(3, 5, geq)) //false
    println(compare(5, 3, geq)) //true
}

Можно ли использовать инфиксный оператор вместо функции в качестве параметра функции?

Например:

func compare(x, y int, comparator <something here>) bool {
    return comparator(x, y)
}

func main() {
    println(compare(3, 5, <=)) //true
    println(compare(5, 3, <=)) //false
    println(compare(3, 5, >=)) //false
    println(compare(5, 3, >=)) //true
}

Или моя лучшая ставка - просто написать обертки для операторов, как в первом примере?

Кроме того, если вышесказанное возможно, возможно ли использовать параметр оператора инфикса с синтаксисом инфикса? Такие как

func compare(x, y int, c <something here>) bool {
    return x c y
}

1 Ответ

0 голосов
/ 02 сентября 2018

Нет, это неправильная программа согласно спецификации языка Go .


Тип функции определен и содержит, помимо прочих терминов, список параметров, каждый из которых состоит из объявления параметра: [ IdentifierList ] [ "..." ] Type.

Для этого требуется, чтобы все параметры функций имели типы, указанные как производные Type, таким образом:

TypeLit = ArrayType | StructType | PointerType | FunctionType | InterfaceType |
          SliceType | MapType | ChannelType

Встроенные операнды (такие как операторы равенства и сравнения) являются внутренними для языка и не представляются здесь как возможные литералы типов.

Более того, спецификация для вызовов функций требует, чтобы аргументы в вызове были однозначными выражениями. Бинарные операторы не являются выражениями .

Соответственно, вы не можете передавать «инфиксные» операторы в качестве аргументов для вызова функции. Вы должны определить свой собственный интерфейс или тип функции, который обернет оператор, и передать это в вашу функцию сравнения.

...