你们能接受一个程序设计语言里面一个内置类型对象的长度和它能迭代的次数不一样这种事情吗?

2019-05-24 23:14:47 +08:00
 vencent

最近在学一门新语言。此语言近年来越来越受欢迎(为了不引战,就不说具体是啥了,大家应该也能猜到),它的确提出了一种有意思的并发编程模型,但我个人认为在语言(语法)设计上很多地方颇为糟糕,其他人也有评论“看着很美好,写起来全是坑”。在这些“坑”中,一致性差是我认为比较难接受的。举例来说:它的 len(string) 为 11,但在 for in 循环中,string 只能迭代 5 次。

因为本人经验不算丰富,想问问大家能接受这么奇怪的设定吗,或者其他语言中也有这么奇怪的事情吗?我个人觉得这种不一致的设计是非常反人类的。

友好讨论别打架:)

4346 次点击
所在节点    程序员
56 条回复
dyxLike
2019-05-25 18:15:16 +08:00
@passerbytiny 准确来说 len 应该不是字节个数,而是 unicode 单元个数吧,一个字符用 utf-8 表示 len 可能是 1/2/3/4 用 utf-16 表示可能是 1 或者 2
love
2019-05-25 18:36:53 +08:00
@Mohanson
> 我玩过的几乎所有现代语言都是这么设计的

我孤陋寡闻了,用过的 java/c#/python/js 都不会这样,除了 go 还有哪个语言这样设计?
love
2019-05-25 18:39:32 +08:00
@dacapoday len 面向底层,那为什么 for-in 就不是面面底层了?我 for 一个个 byte 就不底层了?
cpdyj0
2019-05-25 18:43:47 +08:00
@dacapoday 函数名和语义不一致是好事???
cpdyj0
2019-05-25 18:44:18 +08:00
没咋用过 go,但是这个设计确实很别扭
cpdyj0
2019-05-25 18:47:05 +08:00
@Mohanson 那啥,反正 Java 中的操作是 String 一律存储 UTF-16 (其实这不好),然后返回 UTF-16 码点的数量。严格来说不是字符个数,只能算是 codepoint 数量,不过一般情况下可以等价为字符个数。
lrxiao
2019-05-25 19:05:52 +08:00
问题在于 string 处理的复杂度。。这和语言没什么关系了吧
abcbuzhiming
2019-05-25 19:09:31 +08:00
Go 还是个很年轻的语言,所以有些设计上的问题是很正常的各位,不要神话一门语言,就算它是 google 发明出来的也一样。具体到楼主的问题,我个人的看法是,Go 最开始是设计出来取代的 C 的,非常偏底层,所以字符串这块的抽象就不像其他更高级的语言,我个人认为这个可能会和 Go 的价值取向有关,如果 Go 以后打算进一步去应用层,那么迟早会变的和其它高级语言类似,如果 Go 的想法就是扎根底层,那很可能也就是这样了
tairan2006
2019-05-25 19:17:25 +08:00
Python2 的 len 也是错的,你用中文试试。Java 的 unicode 设计更失败,CPP 就不说了,压根不考虑编码。go 的已经够好用了好吗,转成 rune 数组不就完了。
linvaux
2019-05-25 19:19:02 +08:00
怎么感觉在说 go 呢?
ysc3839
2019-05-25 19:21:15 +08:00
一开始以为说的是 Python。
印象中 Python 是用 wchar_t 来存 Unicode 字符串的,在 Windows 上 wchar_t 是 2 字节的,所以遇到一些占两个 wchar_t 的字符可能会掉坑里?

刚刚去查了一下,Python 3.3 开始引入了 Flexible String Representation https://www.python.org/dev/peps/pep-0393/
可以根据内容来选择 1, 2, 4 字节。
elfive
2019-05-26 06:09:34 +08:00
字节串和字符串的一点点区别
jinliming2
2019-05-26 08:15:50 +08:00
JavaScript 在处理高位 Unicode 也是这样的问题,用 for in 没问题,但是一个字符被拆成多个字符,用 for of 可以正确处理这些字符,但是迭代次数又和 length 不一样。
bringyou
2019-05-26 13:07:38 +08:00
go 迭代 string 的时候,rune 和 byte 的区别吧。
liulaomo
2019-05-26 22:24:23 +08:00
@vencent

> 而 go 语言的 len 函数对于其他内置类型来说获取的是容器的长度(即元素的个数),而对于 string 类型获取的却是字节数。这种奇怪的不一致我认为是它的设计问题。

这是一个误解。Go 种的字符串应该被看作是一个只读字节切片。也就是说,字符串(做为容器)的元素类型为 byte。
liulaomo
2019-05-26 22:30:14 +08:00
但是,遍历一个字符串得到的是 rune 而不是它的 byte 元素,这确实是一个例外 https://gfw.go101.org/article/exceptions.html#container-elements-iteration

Go 里面这样的细节上例外很多,但是 Go 在宏观设计上的一致性比较高,例外很少。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/567457

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX