【问题标题】:Does Go support operator type variables?Go 是否支持运算符类型变量?
【发布时间】:2014-05-02 20:31:24
【问题描述】:

这可能不是一个好问题,因为我不知道有任何编译语言支持此功能,但由于 Go 总是让我感到惊讶,我还是会问它:

为了我自己的练习,我正在用 Go 编写一个小计算器程序。我想知道是否有一种方法可以声明和分配“运算符”类型的变量,例如,我可以这样写:

var o Operator

o = +

var o1 Operator

o1 = /

这样写函数

func DoOperation(a,b int,o Operator) int{

    return a o b

}

(不,我不是在问运算符重载。)

顺便说一句,我不知道有任何编译语言支持这样的事情(我不是这方面的专家)。我确实查看了操作符下的文档,但一无所获。 Go 能再给我一个惊喜吗?

编辑:接受的答案表明 Haskell 支持这一点,

【问题讨论】:

  • 有什么特别的原因被否决了吗?由于 Haskell 支持这一点,根据 @tomwilde 的回答,这不是一个愚蠢的问题,我确实查看了操作符下的文档,但一无所获,但 Go 似乎在“复活节彩蛋”中占有一席之地
  • Io 可以做这样的事情。
  • @dethtron5000 - 有趣。以前从未听说过Io,只是查了一下——我猜这不是主流语言...... :) 我看到它在虚拟机中运行。它会编译成类似于 Java 字节码或 MSIL 的东西吗?

标签: variables go operators variable-assignment


【解决方案1】:

不,Go 运算符不是函数,因此没有有效的右手表达式。它们以通用方式工作,例如加号运算符适用于所有数字类型,也不支持中缀符号 a la haskell。

您必须使用反射编写自己的“软”通用加法函数。

Haskell 是一种可以满足您所有需求的编译语言。

【讨论】:

    【解决方案2】:

    你不能完全按照你说的去做,但你可以使用函数来代替。您必须为每个运算符编写函数,但代码相对较少。

    type BinaryOperator func(a, b int) int
    
    func OpAdd(a, b int) int { return a + b }
    func OpSub(a, b int) int { return a - b }
    
    func ApplyBinaryOperator(a, b int, op BinaryOperator) int {
        return op(a, b)
    }
    

    【讨论】:

    • 抱歉,我不能同时接受这两个答案。但@tomwilde 是第一个,技术上更详细。但是您的解决方法是一个优秀的想法,我可能会实施。
    • 请注意,如果您将 Bi​​naryOperator( ) 放在 func 文字周围,此示例仍然有效:var OpAdd = func(a, b int) int { return a + b } 和 OpSub 类似。跨度>
    • 谢谢拉斯!我更改了代码以纳入您的建议。
    【解决方案3】:

    来自 oop​​ 背景,我开始这样做:

    package main
    
    import "fmt"
    type MyInt int64
    
    func (i * MyInt) Add(n MyInt) * MyInt {
        *i += n
        return i
    }
    
    func (i MyInt) String() string {
        v := int64(i)
        return fmt.Sprintf("0x%x (%d)", v, v)
    }
    
    func main() {
        x := MyInt(10)
        x.Add(10).Add(20).Add(30)
        fmt.Println("x = ", x)
    }
    

    【讨论】:

    • 我更喜欢@Anonymous 回答中的方法——它只不过是很好的老式函数指针,只是使用 Go 风格(使其清晰简单)并保持通用,尽管您的方法也可以使用类似的设计模式。另见How to convert a int value to string in go?
    猜你喜欢
    • 2013-02-21
    • 1970-01-01
    • 2011-08-27
    • 1970-01-01
    • 2022-06-29
    • 2016-01-24
    • 2012-04-25
    • 2012-02-11
    • 2011-07-25
    相关资源
    最近更新 更多