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

发布于 1周前 作者 vueper 来自 Go语言

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

m:=make(map[int]int)
m[0]=0 //map 可以通过下标访问元素

a:=[]int{1,2,3}
b:=[]int{1,2,3}
fmt.Print(a==b) //true
28 回复

不懂就问,运算符重载和这两个有什么关系?为什么不可以这样用?

更多关于Golang Go语言中,不懂就问,go不是没有运算符重载吗,为什么map可以通过下标访问,数组比较可以用==的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


invalid operation: a == b (slice can only be compared to nil)

数组可以 ==,slice 不行。

谢谢大佬 学到了 但是还是不明白数组可以==,按我的理解是两个不同数组的头指针在对比

因为按我的理解下标访问是数组才可以 数组==比较是两个不同数组的头指针在对比

“运算符重载”是很糟糕的命名,“重载”什么了?
正确的叫法应该是不允许为自定义类型定义运算符操作。
显然内置类型不属于自定义类型。

go 的数组在做比较的时候对比的不是指针而是值吧. 可以尝试用 unsafe.Pointer 获取地址再对比, 获取到的两个地址应该是不一样的

明白 感谢!

运算符重载的例子你都举得不对,map 等内置数据结构当然可以用下标比较。因为这是语言规定的一部分。要举例子啊,你应该举 make ,毕竟它可以接受数量不一样的参数。你试试看能不能模仿

不明白这和 make 有什么关系 另外是因为我觉得除了 int 这种基本类型 map 应该是类 应该用 map.getValue(Key)来取得值 (似乎暴露了什么

map[key] = value,不明白和下标有什么关系

你这是学叉了吧

map 那个你是访问的 key, 你把 map 的 key 定为 string 看看

map 你不用这种方式的话你就只有 range 才能获取了…map 没有函数封装也不是 struct,为什么不能这样访问…建议看完圣经…

有些语言,支持重载运算符,内置类型的运算自然通过重载运算符实现,比如 Python 和 Rust 。
有些语言不支持重载运算符,内置类型的运算符就只能通过语言规定。

楼主 Go 语言基础可能需要好好补一下,Go 里的数组类型,不止是与元素的类型有关,还有数据的长度有关,不同长度的数据类型不同,只有相同长度相同类型,才会逐一对比数据内的元素。

Go 不是 java ,map 和运算符重载没关系,== 比较数组的值相等有问题吗

下标访问是万能的编译器,做的代码转换,这些在编译的时候会换改成对应的函数吧

没有运算符重载的意思是运算符重载不给用户使用而已,没说不给语言发明者使用。(手动狗头

我的意思是 map 是内置的,好比你对数组也只能用[index]这样的方法取值,而不能使用.index 这样的方式取值。它本来就是语言的一部分。语言就是这样规定的。
至于为什么提到 make ,因为 make 就是一个看似违反函数调用方式的存在,它一个函数可以有多种函数签名。本质上还是语言作者自己开洞实现或者说这就是语言的一部分,“我用可以,你们使用者用就不行”

go 和 c++不一样。c++对 stl 和用户类是一视同仁的,用户自己可以实现出和 stl 相同的东西。但 go 是为内置数据类型开了天窗的,用户没法自己实现内置类型的。



主要是[]这个运算符 似乎我自定义一个 K-V 容器的话用不了[]来取 value ?

666 学到了
明白
确实是刚学 领教了

这个名字来源于数学、错误迁用和错误翻译。
数学:overload 原本是指同一个符号(数学上的符号,包括 d/dx 或者 A B C 这种)用于多个不同的含义。因为会产生混淆,数学上认为这是一种糟糕的实践。
错误迁用: 工程上其实是用这样一个词来表述『相似的符号通过不同的实现来获得相似的含义』,它产生了表面的一致性( Matrix+Matrix 或者 int+int 当然都应该是 + )。但同样地发生了上述 overload 的问题,用以表示不同的含义(比如 str+str 其实不应该是 str ,更恰当的比如 ++)。
错误翻译:这个词构词有「载」,但「重」到底是 chóng 还是 zhòng 是个问题。看 overload 一词构词上来说,应该是 zhòng ,但这个读音下这个词还是多义。另一方面,根据「重复的名称」似乎又应该是 chóng 。而且这个词在电学上也有「过载」一译法。

”为什么 map 可以通过下标访问“
先问是不是,再问为什么

我觉得这个应该是从无泛型的语言沿用下来的,“重载”一般是多个签名不同的函数(类型、数量不一致)共用同一个名字,而运算符则更接近定义于对应 interface/type class 的泛型函数(或 OO 里所谓的多态),任何类型只要实现了对应的 interface/type class 就能支持相应的操作,不应该再称为“重载”。

OO 的多态有两种,一种是唯名论的 trait ;另一种是唯实论的 interface 。 (以 Ponylang 的术语命名)
(注:Java 的 interface 实际上是 trait )
( Python 原本是唯实论的,后来搞出唯名论,现在又做了点唯实论的东西,属实是墙头草)
重载只是单纯的「同形不同义」之表述,并不实质上区分函数名、关键词、操作符,甚至发源在 OO 之前。这都属于文法范畴,语义层面上考虑时不建议深究它们的区别,毕竟 Lisp 早已经大一统了, + - 都是函数名。

duck typing 和显式声明的区别并不重要。我不是指区分 operator 和 function ,而是说通过所谓多态、泛型,用户并没有为自己的类型实现+,而是实现其所定义的 interface 需要的方法。使用时还是调用的原本的+,没有复用已有的名字,所以不该称为重载。

在Go语言中,确实没有运算符重载这一特性,这是为了保持语言的简洁性和一致性。然而,你提到的map通过下标访问和数组可以使用==进行比较,这两个操作是Go语言设计时内置的特殊处理,而非运算符重载的结果。

对于map通过下标访问(如value := map[key]),这是Go语言对map类型的一种语法糖,允许开发者以类似数组下标的方式读取或设置map中的值。这实际上是Go语言编译器和运行时提供的便捷语法,而非通过运算符重载实现的。

至于数组可以使用==进行比较,这是Go语言在编译期就确定的一种比较机制。对于长度相同且类型相同的数组,Go语言允许使用==运算符直接比较其所有元素是否相等。这种比较是浅比较,且仅适用于数组类型,不适用于切片(slice),因为切片包含指向底层数组的指针和长度信息,直接使用==比较的是指针和长度,而非元素内容。

总的来说,Go语言通过内置的特殊处理来支持map的下标访问和数组的比较,而非通过运算符重载这一特性。这种设计保持了Go语言的简洁性和易用性,同时避免了运算符重载可能带来的复杂性和混淆。

回到顶部