V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
seekseat
V2EX  ›  Go 编程语言

运算符重载有什么实际用途?感觉很鸡肋

  •  
  •   seekseat · 68 天前 · 5447 次点击
    这是一个创建于 68 天前的主题,其中的信息可能已经有所发展或是发生改变。

    看到很多人在讨论...但这玩意有啥作用,工作这么多年完全没 get 到

    53 条回复    2024-09-09 19:26:15 +08:00
    nino
        1
    nino  
       68 天前   ❤️ 1
    对写 DSL 和 库的人才有意义,能让 API 更语义化,或者语句更像数学公式
    cwek
        2
    cwek  
       68 天前   ❤️ 1
    "语句更像数学公式",就是这个。
    hanxiV2EX
        3
    hanxiV2EX  
       68 天前 via Android
    golang 要支持了吗?
    mainjzb
        5
    mainjzb  
       68 天前   ❤️ 6
    实现矩阵相乘 ,相加
    result := a1 * a2 + a3
    而不是
    result := sum(mul(a1, a2) , a3)

    比如连接
    result := s1 + s2
    而不是
    result := strings.append(s1, s2)

    比如实现一个 @ 代替 must( func f() ) 来简化错误处理
    result := @runServer()
    而不是
    result := must(runServer())

    比如检测一堆向量是否能形成环
    sum := vector(0,0)
    for _,v := range vs{
    sum += v
    }
    if sum == vector(0,0) {
    // 形成了环
    }

    而不是

    sum := vector(0,0)
    for _, v:= range vs{
    sum = vectors.add(sum, v)
    }
    if sum.x == 0 && sum.y == 0 {
    // 形成了环
    }
    laminux29
        6
    laminux29  
       68 天前
    举个更简单的例子,无论 C++、Java 、C#、Python ,大家都喜欢用 Class 或 Struct 。这玩意本质上来说,就是对基础数据结构的包装,或者说是语法糖。如果没有 Class 、Struct ,你自己得用一大堆基础数据结构的数组或 List ,来自行管理这些玩意,于是,这个问题,就转换为:

    Class 、Struct 有什么实际用途?
    Ayanokouji
        7
    Ayanokouji  
       68 天前
    运算符重载 我只佩服 kotlin
    xgdgsc
        8
    xgdgsc  
       68 天前 via Android
    Sawyerhou
        9
    Sawyerhou  
       68 天前 via Android   ❤️ 11
    举个栗子

    Python 里 pathlib 拼接路径,
    不必用+,不必用 join ,用/

    dir / "stem.csv"

    非常直觉,高效又易读,
    每次我用到都感慨这个重载太漂亮了。
    PopRain
        10
    PopRain  
       68 天前
    第一次用 Java , 被 BigDecimal interest = loanAmount.multiply(interestRate) 震惊了。。。。。
    ty29022
        11
    ty29022  
       68 天前   ❤️ 5
    @Sawyerhou 这个我认为恰恰是个反面例子
    在我看来编程语言中 / 就是除法,读出来是除法,做的事情也该是除法
    这和向量和矩阵操作这种符合数学直观逻辑的用法很不一样
    不过这很 python 就是了,个人感觉 python 总是做一些自以为”自然“的事情
    wlingxiao
        12
    wlingxiao  
       68 天前
    建议看看 scala ,体会下操作符满天飞的感觉。
    cmdOptionKana
        13
    cmdOptionKana  
       68 天前
    确实很鸡肋,实用性不强,主要用途是耍帅。
    GeruzoniAnsasu
        14
    GeruzoniAnsasu  
       68 天前
    @ty29022
    那 numpy 重载切片运算符倒确实还挺自然的
    shintendo
        15
    shintendo  
       68 天前   ❤️ 1
    @ty29022 我感觉 python 的三目也有点……
    masterclock
        16
    masterclock  
       68 天前
    没有操作符重载写点计算的东西简直就是折磨啊
    wxf666
        17
    wxf666  
       68 天前
    @ty29022 #11 为嘛 / 只能是除法的意思,而不能是分隔符呢?(比如斜杠青年)

    那同理,字符串拼接,也不该用 +,而是像拼接矩阵那样,[str1 str2 str3] ?

    wxf666
        18
    wxf666  
       68 天前
    @PopRain #10 有没有 greaterEqualThan() 啥的。。

    还是叫 greaterThanOrEqualTo()。。

    Sawyerhou
        19
    Sawyerhou  
       68 天前
    @ty29022 重载运算符跟语言没有关系,支持重载都可以用/拼接路径。

    做数学的应该都知道符号是非常不够用的,符号在不同域下定义不一样很正常,
    *在初等数学里是乘法,高等里就是卷积了。

    而且路径的对象类型不属于数学对象,没有除法
    就像,C++里面 IO 流用<<和>>,IO 本身也没有比较大小的必要。
    newtype0092
        20
    newtype0092  
       68 天前
    想想确实除了在学校里课上花了好大功夫学了一番,实际工作中并没有怎么用上过。

    每次想实践一下,总觉得我写的那些东西还不配让别人迁就我来适应一个新的运算符用法,老老实实 function 加参数就好。
    009694
        21
    009694  
       68 天前 via iPhone   ❤️ 1
    @ty29022 你这种想法极其傲慢。。 键盘上半角符号就这么几个 照你这说法全都只能用于原始的数学含义 那还真出什么运算符重载 全都只支持基础类型就行了
    nagisaushio
        22
    nagisaushio  
       68 天前 via Android
    @ty29022 @Sawyerhou 有种给 iostream 左右移的美感(开玩笑)
    y1y1
        23
    y1y1  
       68 天前
    确实当初下了好大的功夫
    wkla
        24
    wkla  
       68 天前
    在 C++里,比如你写个类,重载一下移位运算符,就可以用左移右移来做输入输出 << >>

    C++ 的 filesystem 标准库,也可以用 / 运算符来算路径。比如 std::filesystem::path outputPath = std::filesystem::path("parent_dir") / relativePath;

    你写一套矩阵库,别人想用起来要是可以直接用 + - * / ,直接 << 输出,可能学习成本就低一点,别人会爽一点。

    虽然我确实觉得主要是用来耍帅🤣
    f0rb
        25
    f0rb  
       68 天前
    那路径里面 windows 的\怎么处理呢,只在 linux 上开发?
    aliipay
        26
    aliipay  
       68 天前
    @009694 说实在的,这就是 shit🕳,连标点都没有
    adoal
        27
    adoal  
       68 天前   ❤️ 1
    @ty29022 运维人表示 / 显然是路径分割符……话说回来,数学课本里除法写一行用除号 ÷ ,写多行用分数线,斜线并不是主流啊。
    agagega
        28
    agagega  
       68 天前
    严格一点说,大部分语言的运算符即使不支持用户重载,也是已经重载过的了。比如加法 + 严格来说对整数和浮点数是完全不一样的两种操作,像 OCaml 就会区分整数的 + 和浮点数的 +.

    所以严格纠结所谓数学上的含义没有意义……
    inframe
        29
    inframe  
       68 天前
    @ty29022 #11 有点教条主义,从实用主义的角度出发工具的发明应该是提高生产效率的,
    “黑猫白猫不管什么猫,能让开发人员更加快速的完成开发任务就是好猫”
    whusnoopy
        30
    whusnoopy  
       68 天前
    比如我定义了一个向量类型 P ,有 x/y 两个坐标,向量可以加一个向量到新的位置,就是 p3(x3, y3) = (x1+x2, y1+y2), 如果支持运算符重载,在向量类型定义里我重载掉加法,这样我就只要写 p3 = p1 + p2 就行,而不用写 p3.x = p1.x + p2.x ,p3.y = p1.y + p2.y
    p1gd0g
        31
    p1gd0g  
       68 天前
    说白了还是看业务,总没必要硬着头皮用吧?
    mightybruce
        32
    mightybruce  
       68 天前
    这个是语言哲学语言设计的范畴,无所谓好坏,支持运算符重载能找到一堆理由,不支持运算符重载的也有一堆理由。

    新语言如 rust 也有通过 trait 来支持运算符重载的
    liuminghao233
        33
    liuminghao233  
       68 天前 via iPhone
    10 个矩阵相乘,你用 golang 写一下吧
    GeekGao
        34
    GeekGao  
       68 天前
    高级抽象:除 1 楼提到的 DSL 外,还有场景,例如 ORM
    butanediol2d
        35
    butanediol2d  
       68 天前   ❤️ 1


    情绪化日志( doge
    default996
        36
    default996  
       68 天前
    @butanediol2d 哈哈,为什么不把表情符号也追加到日志中
    wanguorui123
        37
    wanguorui123  
       68 天前   ❤️ 1
    C# 里面运算符重载可以实现+注册和-移除方法实现更直观的订阅机制
    Biem
        38
    Biem  
       68 天前
    @ty29022 读出来是除法只能说明一件事,那就是命名不规范不能体现变量或者函数的实际意义。
    Kauruus
        39
    Kauruus  
       68 天前
    你用过 Go 的 math/big (或者其他 decimal 包)就知道了,他们的加减乘除是这样的:

    ```
    func (z *Int) Add(x, y *Int) *Int
    func (z *Int) Sub(x, y *Int) *Int
    func (z *Int) Mul(x, y *Int) *Int
    func (z *Int) Quo(x, y *Int) *Int
    ```

    本来一行就能写完公式,你用上面的 API 要不断搞中间变量,硬是写成十几二十行,每次写点复杂的计算公式或者 code review ,我就头大,非常想要运算符重载。
    sazima
        40
    sazima  
       68 天前
    比如这个, 运算符就重载了,sesseion.User.filter(User.name == User.nickname | User.age < 15 )
    araraloren
        41
    araraloren  
       68 天前
    所以,go 是不支持么,理由是什么?然后怎么就推翻了自己
    tool2dx
        42
    tool2dx  
       68 天前 via Android
    最明显就是向量数学类,能和普通的语法一样加减乘除。
    别的似乎也没明显好处。
    yb2313
        43
    yb2313  
       68 天前
    又想写 equals 了是吧
    nenseso
        44
    nenseso  
       67 天前
    ==啊这种两个数据结构的比较重载一下还是很好用的,也很好读
    wsping
        45
    wsping  
       67 天前   ❤️ 1
    自定义类要排序的话就必须重载小于号
    DOLLOR
        46
    DOLLOR  
       67 天前
    a + b 本质就是 a.add(b) 的语法糖。
    如果平时开发都是以 crud 为主,那确实看起来差别不大。
    但如果是以数学计算为主的开发,重载后的+-*/之类的符号是比方法名看得更舒服的。
    lance6716
        47
    lance6716  
       67 天前 via Android
    让自定义结构体长的跟内置类型一样,不过个人觉得没必要,妈的 debug 的时候看上去人畜无害的一样结果是个重载
    guiyumin
        48
    guiyumin  
       67 天前
    @wsping nice
    dragondove
        49
    dragondove  
       67 天前
    运算符重载有个好处是可以利用运算符的优先级减少括号层数而使代码变得易读。例如创建 sql 的 dsl 时,如果使用 where ((a add b) eq c) and (d eq e) 对比 where a + b == c && d == e 来说,后者更易读
    jorneyr
        50
    jorneyr  
       67 天前
    @PopRain 本来没啥感触,您一提到 BigDecimal 我就有点炸裂了。
    caiqichang
        51
    caiqichang  
       67 天前
    建议看一下《 effective c++》和《 more effective c++》中运算符重载的相关内容
    cybort
        52
    cybort  
       66 天前 via Android
    高级语言有什么用处?写汇编不行吗?😆
    Rickkkkkkk
        53
    Rickkkkkkk  
       66 天前
    你肯定期望能写 "sss" + "ddd" 这种啊...也符合直觉
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5706 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 06:29 · PVG 14:29 · LAX 22:29 · JFK 01:29
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.