苹果现在 bug 越来越多的原因找到了

2 天前
 qdwang

这里大家都是程序员,只要做完这个题,就知道为什么苹果会有那么多 bug 了

// 这是一段 swift 代码

var hello = [10, 20, 30, 40, 50, 60]
var foo = hello[2..<5] // 表示索引范围是 2 ,3 ,4
foo[2] = 0
print(foo) 

// 先看看你的程序员直觉,输出结果是什么

然后随便 google 找个 swift playground 运行这段代码,你就知道为什么苹果现在 bug 越来越多了。

11449 次点击
所在节点    Apple
109 条回复
deplives
1 天前
kfpenn
1 天前
liuhan907
1 天前
这个输出 [0, 40, 50] 不才是符合直觉的?
cpper
1 天前
每个语言有每个语言的用法,不要陷入奇巧淫技的细节中
liuhan907
1 天前
哦,大意了,foo[2] 啊。那这是傻逼设计,我看的不够仔细啊 -_-
IDAEngine
1 天前
这是一个关于 Swift 数组切片( Array Slice )行为的有趣问题。

我的“程序员直觉”告诉我,输出结果是:

[0, 40, 50]
解释(为什么我的直觉是这样):

切片操作:

var hello = [10, 20, 30, 40, 50, 60]

var foo = hello[2..<5] 创建了一个数组切片( Array Slice )。这个切片包含 hello 中索引 2,3,4 的元素。

foo 此时是 [30, 40, 50]。

关键点:数组切片的索引继承了原数组的索引。所以 foo 内部元素的索引是 2,3,4 ,而不是从 0 开始。

修改切片:

foo[2] = 0 尝试修改 foo 中索引为 2 的元素。

在 foo 中,索引 2 对应的值是 30 。

修改后,foo 变成了 [0, 40, 50](注意,尽管内部值变了,它的索引结构仍然是 2,3,4 )。

打印切片:

print(foo) 打印切片的内容。Swift 在打印数组切片时,会打印其包含的元素值。

因此,输出是 [0, 40, 50]。
november
1 天前
@cpstar 主楼的代码应该是对标的 js 的 Array.slice(2,5)
ccnoobs
1 天前
@IDAEngine "在 foo 中,索引 2 对应的值是 30 。" 不知道你怎么想的
yuanxing008
1 天前
可能 go 和 python 写的太久了 我的第一直觉就是[0,40,50]

后面看你们讨论才发现这个设计很扯,但是写习惯了就好了😁
2en
1 天前
居然不是 30,40,0
leeg810312
1 天前
@IDAEngine 你的直觉才有问题。无论是创建新数组,还是视图,都不该是这样的行为。按业务逻辑,这段代码描述应该是这样,从 A 数组中取第 2-4 (从 0 开始)的元素,作为 B 数组,B 数组的第 2 个元素值改为 0 。关键点,B 的第 2 个元素,实际行为却去改 A 的第 2 个,这完全是反直觉的,即使 B 是视图,非实际创建的新数组,也应当把 B 当作一个逻辑上独立的数组去使用。
PlG5sBkXD1ziLeGB
1 天前
@yuanxing008 啊?你用过 go 的 slice 吗兄弟,还是你把 `foo[2] = 0` 看成 `hello[2] = 0`了
cpstar
1 天前
@november 27# 如果是 js ,那会生成一个新的副本,foo_js 是{"0":30,"1":40,"2":50},然而按照 21#,更像是 foo 就是 hello ,修改了 foo 一并修改 hello ,只不过限定了 foo 的游标只有 2 、3 、4 取值,如果 foo[1]是不是要报错。
ripperdev
1 天前
@yuanxing008 go 不是这样啊,输出肯定是[30 40 0]
superrichman
1 天前
@yuanxing008 #28 你这 python 没学好啊 🐶 python 里面是 [30, 40, 0]

一行命令跑出来就知道了
python -c "a=[10,20,30,40,50,60];b=a[2:5];b[2]=0;print(b)"
guanhui07
1 天前
之前我也学了下 swift 的语法..
leeg810312
1 天前
@yuanxing008 你的直觉错了。go 我不知道,python 的切片是创建一个新 list
a = [0, 2, 4, 6, 8, 10]
b = a[2:5]
b[0] = 3
b[2] = 9
print(a)
print(b)
输出:
[0, 2, 4, 6, 8, 10]
[3, 6, 9]
wangkun2012324
1 天前
正确的用法永远是使用 startIndex 和 offset/advanced
```
var hello = [10, 20, 30, 40, 50, 60]
var foo = hello[2..<5] // 表示索引范围是 2 ,3 ,4
foo[foo.startIndex.advanced(by: 2)] = 0
print(foo) // [30, 40, 0]

```
junj2121
1 天前
C 出生的人 一看就知道结果啊。
这种赋值逻辑肯定是从指针赋值上考虑。
都觉得 C 垃圾,其实并不然
noErr
1 天前
js 仔采用 switft

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

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

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

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

© 2021 V2EX