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

不懂就问, go 不是没有运算符重载吗,为什么 map 可以通过下标访问,数组比较可以用==

  •  
  •   jackiejkl · 2021-11-28 17:06:12 +08:00 · 3783 次点击
    这是一个创建于 851 天前的主题,其中的信息可能已经有所发展或是发生改变。
    m:=make(map[int]int)
    m[0]=0 //map 可以通过下标访问元素
    
    a:=[]int{1,2,3}
    b:=[]int{1,2,3}
    fmt.Print(a==b) //true
    
    luguhu
        1
    luguhu  
       2021-11-28 17:12:45 +08:00 via iPhone
    不懂就问,运算符重载和这两个有什么关系?为什么不可以这样用?
    SuperMild
        2
    SuperMild  
       2021-11-28 17:17:35 +08:00
    invalid operation: a == b (slice can only be compared to nil)

    数组可以 ==,slice 不行。
    jackiejkl
        3
    jackiejkl  
    OP
       2021-11-28 17:28:08 +08:00
    @SuperMild 谢谢大佬 学到了 但是还是不明白数组可以==,按我的理解是两个不同数组的头指针在对比
    jackiejkl
        4
    jackiejkl  
    OP
       2021-11-28 17:29:09 +08:00
    @luguhu 因为按我的理解下标访问是数组才可以 数组==比较是两个不同数组的头指针在对比
    Buges
        5
    Buges  
       2021-11-28 17:33:51 +08:00 via Android
    “运算符重载”是很糟糕的命名,“重载”什么了?
    正确的叫法应该是不允许为自定义类型定义运算符操作。
    显然内置类型不属于自定义类型。
    luguhu
        6
    luguhu  
       2021-11-28 17:40:30 +08:00   ❤️ 1
    @jackiejkl go 的数组在做比较的时候对比的不是指针而是值吧. 可以尝试用 unsafe.Pointer 获取地址再对比, 获取到的两个地址应该是不一样的
    jackiejkl
        7
    jackiejkl  
    OP
       2021-11-28 17:55:29 +08:00
    @luguhu 明白 感谢!
    neoblackcap
        8
    neoblackcap  
       2021-11-28 17:55:49 +08:00
    运算符重载的例子你都举得不对,map 等内置数据结构当然可以用下标比较。因为这是语言规定的一部分。要举例子啊,你应该举 make ,毕竟它可以接受数量不一样的参数。你试试看能不能模仿
    jackiejkl
        9
    jackiejkl  
    OP
       2021-11-28 18:01:52 +08:00
    @neoblackcap 不明白这和 make 有什么关系 另外是因为我觉得除了 int 这种基本类型 map 应该是类 应该用 map.getValue(Key)来取得值 (似乎暴露了什么
    yyf1234
        10
    yyf1234  
       2021-11-28 18:28:12 +08:00 via iPhone
    map[key] = value,不明白和下标有什么关系
    lysS
        11
    lysS  
       2021-11-28 19:33:22 +08:00
    你这是学叉了吧

    map 那个你是访问的 key, 你把 map 的 key 定为 string 看看
    ClarkAbe
        12
    ClarkAbe  
       2021-11-28 19:42:57 +08:00
    map 你不用这种方式的话你就只有 range 才能获取了........map 没有函数封装也不是 struct,为什么不能这样访问.......建议看完圣经.....
    leoleoasd
        13
    leoleoasd  
       2021-11-28 19:55:21 +08:00
    有些语言,支持重载运算符,内置类型的运算自然通过重载运算符实现,比如 Python 和 Rust 。
    有些语言不支持重载运算符,内置类型的运算符就只能通过语言规定。
    Cbdy
        14
    Cbdy  
       2021-11-28 19:59:25 +08:00
    大道至简
    qq2562524625
        15
    qq2562524625  
       2021-11-28 20:21:07 +08:00
    楼主 Go 语言基础可能需要好好补一下,Go 里的数组类型,不止是与元素的类型有关,还有数据的长度有关,不同长度的数据类型不同,只有相同长度相同类型,才会逐一对比数据内的元素。
    Nasei
        16
    Nasei  
       2021-11-28 20:46:35 +08:00
    Go 不是 java ,map 和运算符重载没关系,== 比较数组的值相等有问题吗
    iQXQZX
        17
    iQXQZX  
       2021-11-28 21:23:58 +08:00
    下标访问是万能的编译器,做的代码转换,这些在编译的时候会换改成对应的函数吧
    noroot
        18
    noroot  
       2021-11-28 21:39:26 +08:00
    没有运算符重载的意思是运算符重载不给用户使用而已,没说不给语言发明者使用。(手动狗头
    neoblackcap
        19
    neoblackcap  
       2021-11-28 22:06:24 +08:00
    @jackiejkl 我的意思是 map 是内置的,好比你对数组也只能用[index]这样的方法取值,而不能使用.index 这样的方式取值。它本来就是语言的一部分。语言就是这样规定的。
    至于为什么提到 make ,因为 make 就是一个看似违反函数调用方式的存在,它一个函数可以有多种函数签名。本质上还是语言作者自己开洞实现或者说这就是语言的一部分,“我用可以,你们使用者用就不行”
    mzmssg
        20
    mzmssg  
       2021-11-28 22:47:40 +08:00
    go 和 c++不一样。c++对 stl 和用户类是一视同仁的,用户自己可以实现出和 stl 相同的东西。但 go 是为内置数据类型开了天窗的,用户没法自己实现内置类型的。
    jackiejkl
        21
    jackiejkl  
    OP
       2021-11-29 00:03:50 +08:00
    @yyf1234
    @lysS
    主要是[]这个运算符 似乎我自定义一个 K-V 容器的话用不了[]来取 value ?
    jackiejkl
        22
    jackiejkl  
    OP
       2021-11-29 00:05:31 +08:00
    @neoblackcap 666 学到了
    @mzmssg 明白
    @qq2562524625 确实是刚学 领教了
    2i2Re2PLMaDnghL
        23
    2i2Re2PLMaDnghL  
       2021-11-29 09:58:56 +08:00
    @Buges 这个名字来源于数学、错误迁用和错误翻译。
    数学:overload 原本是指同一个符号(数学上的符号,包括 d/dx 或者 A B C 这种)用于多个不同的含义。因为会产生混淆,数学上认为这是一种糟糕的实践。
    错误迁用: 工程上其实是用这样一个词来表述『相似的符号通过不同的实现来获得相似的含义』,它产生了表面的一致性( Matrix+Matrix 或者 int+int 当然都应该是 + )。但同样地发生了上述 overload 的问题,用以表示不同的含义(比如 str+str 其实不应该是 str ,更恰当的比如 ++)。
    错误翻译:这个词构词有「载」,但「重」到底是 chóng 还是 zhòng 是个问题。看 overload 一词构词上来说,应该是 zhòng ,但这个读音下这个词还是多义。另一方面,根据「重复的名称」似乎又应该是 chóng 。而且这个词在电学上也有「过载」一译法。
    whyso
        24
    whyso  
       2021-11-29 10:38:01 +08:00
    ”为什么 map 可以通过下标访问“
    先问是不是,再问为什么
    Buges
        25
    Buges  
       2021-11-29 12:41:02 +08:00 via Android
    @2i2Re2PLMaDnghL 我觉得这个应该是从无泛型的语言沿用下来的,“重载”一般是多个签名不同的函数(类型、数量不一致)共用同一个名字,而运算符则更接近定义于对应 interface/type class 的泛型函数(或 OO 里所谓的多态),任何类型只要实现了对应的 interface/type class 就能支持相应的操作,不应该再称为“重载”。
    2i2Re2PLMaDnghL
        26
    2i2Re2PLMaDnghL  
       2021-11-29 13:10:44 +08:00
    @Buges OO 的多态有两种,一种是唯名论的 trait ;另一种是唯实论的 interface 。 (以 Ponylang 的术语命名)
    (注:Java 的 interface 实际上是 trait )
    ( Python 原本是唯实论的,后来搞出唯名论,现在又做了点唯实论的东西,属实是墙头草)
    重载只是单纯的「同形不同义」之表述,并不实质上区分函数名、关键词、操作符,甚至发源在 OO 之前。这都属于文法范畴,语义层面上考虑时不建议深究它们的区别,毕竟 Lisp 早已经大一统了, `+` `-` 都是函数名。
    Buges
        27
    Buges  
       2021-11-29 13:37:44 +08:00 via Android
    @2i2Re2PLMaDnghL duck typing 和显式声明的区别并不重要。我不是指区分 operator 和 function ,而是说通过所谓多态、泛型,用户并没有为自己的类型实现`+`,而是实现其所定义的 interface 需要的方法。使用时还是调用的原本的`+`,没有复用已有的名字,所以不该称为重载。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1054 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 22:40 · PVG 06:40 · LAX 15:40 · JFK 18:40
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.