V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
qdwang
V2EX  ›  Apple

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

  •  
  •   qdwang · 1 天前 · 9578 次点击

    这里大家都是程序员,只要做完这个题,就知道为什么苹果会有那么多 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 越来越多了。

    96 条回复    2025-10-27 23:59:14 +08:00
    ourstars
        1
    ourstars  
       1 天前   ❤️ 14
    直觉理解是[30,40,0],但是运行之后是[0,40,50]。
    foo 用的是 hello 的索引范围造成了[0,40,50]的结果。
    qdwang
        2
    qdwang  
    OP
       1 天前 via iPhone
    @ourstars 对,swift 设计了这个反程序员直觉的语义。导致你去问 ai ,也有一大堆 ai 会回答错误。
    TianDogK48
        3
    TianDogK48  
       23 小时 36 分钟前 via iPhone   ❤️ 1
    目测这个语法不常用,所以问题应该不大; go 里面 slice 扩容,也有坑,但是目测 go 的 slice 很少用,都是直接 make
    raycool
        4
    raycool  
       23 小时 34 分钟前
    看来都是 slice 的不同理解导致的。
    smlcgx
        5
    smlcgx  
       23 小时 31 分钟前 via iPhone
    这样看起来 swift 更偏向自然语言一点,几就是几
    butanediol2d
        6
    butanediol2d  
       22 小时 53 分钟前
    hello 是 Array<Int>
    foo 是 ArraySlice<Int>
    craftsmanship
        7
    craftsmanship  
       22 小时 39 分钟前 via Android
    如此说来 JS 早先那些垃圾设计可能导致的 bug 只会更多。。
    xuejianxianzun
        8
    xuejianxianzun  
       21 小时 1 分钟前
    @craftsmanship 怎么又扯到 js 了,js 在这个场景里没有反直觉的行为。
    hash
        9
    hash  
       17 小时 21 分钟前   ❤️ 1
    系统层核心实现是一坨屎,与语言设计无关
    Building
        10
    Building  
       16 小时 21 分钟前
    都按直觉那不同语言反人类的语法简直不要太多,当然不影响 Swift String 的设计才是最为逆天的东西
    cpstar
        11
    cpstar  
       15 小时 42 分钟前
    @xuejianxianzun 8# 以我不动 swift ,和 1#的情况,我觉得基本上就是 js 的逻辑:
    foo_js[2]=hello[2]/*30*/,foo_js[3]=hello[3]/*40*/,foo_js[4]=hello[4]/*50*/

    foo_js[0]=undefined,foo_js[1]=undefined
    于是
    foo_js[2]=0 之后,foo_js={"2":0,"3":40,"4":50}
    Greendays
        12
    Greendays  
       15 小时 38 分钟前   ❤️ 1
    和语言关系不大的,既然做了开发掌握这个语言的语法是基本要求。Bug 多只是需求超过了能力,不得不赶工和减少测试流程造成的。
    Lin0936
        13
    Lin0936  
       15 小时 31 分钟前
    再逆天的语言也该经过测试啊
    june4
        14
    june4  
       15 小时 27 分钟前
    @craftsmanship js 真没有啥绕不过去的垃圾设计,特别是 ts 上身后,底子非常干净纯洁,现在只有一个日常使用我觉得不爽,就是搞出二个 null/undefined 类型。
    xiangyuecn
        15
    xiangyuecn  
       15 小时 20 分钟前
    苹果拉的屎就是香,没啥毛病 能咽下去的
    freeloop1
        16
    freeloop1  
       15 小时 8 分钟前
    那个 foreach 的语法我是最蚌埠住的,我总感觉是少写了括号啥的,太难受了。
    a33291
        17
    a33291  
       15 小时 3 分钟前
    foo 是 hello 的视图吧? 现在很多语言/库都提供这种东西,减少 copy,不过大部分是只读的比较合理
    cookii
        18
    cookii  
       14 小时 50 分钟前 via Android
    @a33291 视图通常只读会好一点
    fadaixiaohai
        19
    fadaixiaohai  
       14 小时 44 分钟前
    从 swift6 开始越来越复杂,关键词越搞越多,问题是有些关键词编译器都支持不太好,搞不好就容易 crash ,对新人也不太友好
    PlG5sBkXD1ziLeGB
        20
    PlG5sBkXD1ziLeGB  
       14 小时 41 分钟前 via iPhone
    swift 的语法真是丑到爆,OC 的语法虽然跟裹脚布一样长,但是可读性非常强
    deplives
        21
    deplives  
       14 小时 38 分钟前
    kfpenn
        22
    kfpenn  
       14 小时 35 分钟前
    liuhan907
        23
    liuhan907  
       14 小时 22 分钟前   ❤️ 1
    这个输出 [0, 40, 50] 不才是符合直觉的?
    cpper
        24
    cpper  
       14 小时 19 分钟前
    每个语言有每个语言的用法,不要陷入奇巧淫技的细节中
    liuhan907
        25
    liuhan907  
       14 小时 14 分钟前   ❤️ 1
    哦,大意了,foo[2] 啊。那这是傻逼设计,我看的不够仔细啊 -_-
    IDAEngine
        26
    IDAEngine  
       14 小时 13 分钟前
    这是一个关于 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
        27
    november  
       14 小时 10 分钟前 via iPhone   ❤️ 1
    @cpstar 主楼的代码应该是对标的 js 的 Array.slice(2,5)
    ccnoobs
        28
    ccnoobs  
       14 小时 8 分钟前
    @IDAEngine "在 foo 中,索引 2 对应的值是 30 。" 不知道你怎么想的
    yuanxing008
        29
    yuanxing008  
       14 小时 5 分钟前
    可能 go 和 python 写的太久了 我的第一直觉就是[0,40,50]

    后面看你们讨论才发现这个设计很扯,但是写习惯了就好了😁
    2en
        30
    2en  
       14 小时 2 分钟前
    居然不是 30,40,0
    leeg810312
        31
    leeg810312  
       13 小时 58 分钟前   ❤️ 3
    @IDAEngine 你的直觉才有问题。无论是创建新数组,还是视图,都不该是这样的行为。按业务逻辑,这段代码描述应该是这样,从 A 数组中取第 2-4 (从 0 开始)的元素,作为 B 数组,B 数组的第 2 个元素值改为 0 。关键点,B 的第 2 个元素,实际行为却去改 A 的第 2 个,这完全是反直觉的,即使 B 是视图,非实际创建的新数组,也应当把 B 当作一个逻辑上独立的数组去使用。
    PlG5sBkXD1ziLeGB
        32
    PlG5sBkXD1ziLeGB  
       13 小时 56 分钟前 via iPhone
    @yuanxing008 啊?你用过 go 的 slice 吗兄弟,还是你把 `foo[2] = 0` 看成 `hello[2] = 0`了
    cpstar
        33
    cpstar  
       13 小时 54 分钟前
    @november 27# 如果是 js ,那会生成一个新的副本,foo_js 是{"0":30,"1":40,"2":50},然而按照 21#,更像是 foo 就是 hello ,修改了 foo 一并修改 hello ,只不过限定了 foo 的游标只有 2 、3 、4 取值,如果 foo[1]是不是要报错。
    ripperdev
        34
    ripperdev  
       13 小时 53 分钟前
    @yuanxing008 go 不是这样啊,输出肯定是[30 40 0]
    superrichman
        35
    superrichman  
       13 小时 52 分钟前   ❤️ 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
        36
    guanhui07  
       13 小时 51 分钟前
    之前我也学了下 swift 的语法..
    leeg810312
        37
    leeg810312  
       13 小时 50 分钟前
    @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
        38
    wangkun2012324  
       13 小时 48 分钟前   ❤️ 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
        39
    junj2121  
       13 小时 48 分钟前
    C 出生的人 一看就知道结果啊。
    这种赋值逻辑肯定是从指针赋值上考虑。
    都觉得 C 垃圾,其实并不然
    noErr
        40
    noErr  
       13 小时 47 分钟前
    js 仔采用 switft
    Torpedo
        41
    Torpedo  
       13 小时 44 分钟前
    @june4 #14 这两个可以不分的。主流库里,常见的只有 react 组件的返回和 json 严格区分了这两个。js 判断 null 和 undefined 如果不分,直接用 a!=null 判断就行了
    idonttellyou
        42
    idonttellyou  
       13 小时 39 分钟前
    为什么不是[30, 40, 0]呢...
    V2Try
        43
    V2Try  
       13 小时 37 分钟前 via iPhone
    这个确实奇怪,如果
    foo[2] = 0
    换成
    hello[2] = 0

    结果是不是一样的?
    Wanex
        44
    Wanex  
       13 小时 36 分钟前
    先别管 swift 符不符合直觉,也别管 js 有没有同样的问题,总之先骂 js 再说🤣
    november
        45
    november  
       13 小时 34 分钟前 via iPhone
    @cpstar 其实 #27 的答案是 ai 结果,实际运行结果是 hello 没变。
    所以更验证了楼主说的“一堆 ai 回答错”。233333
    ChrisFreeMan
        46
    ChrisFreeMan  
       13 小时 33 分钟前
    @idonttellyou 因为很多人理所当然的认为 foo 是拷贝了一个新的数组,实际上 foo[2]指向了原来的数组,foo 只是引用了愿数组 hello 。
    ufan0
        47
    ufan0  
       13 小时 32 分钟前
    @junj2121 以此举例不大合适吧,C 有明确的指针概念,甚至初学者都会接触到。
    PlG5sBkXD1ziLeGB
        48
    PlG5sBkXD1ziLeGB  
       13 小时 29 分钟前
    @ChrisFreeMan #46 按照你的说法,foo[2]指向原来的数组,那修改 foo[2]后原来的数组是不是应该改变呢
    Huelse
        49
    Huelse  
       13 小时 28 分钟前
    确实反直觉
    beimenjun
        50
    beimenjun  
    PRO
       13 小时 28 分钟前
    这个并不是苹果现在 bug 越来越多的原因。

    我还以为是讲技术债之类的,结果居然是吐槽 Swift 的语法。真的是浪费时间。
    ChrisFreeMan
        51
    ChrisFreeMan  
       13 小时 28 分钟前
    @idonttellyou 好吧,我搞错了,自己试了下,原数组并没有改变值
    ChrisFreeMan
        52
    ChrisFreeMan  
       13 小时 27 分钟前
    @PlG5sBkXD1ziLeGB 我刚刚试了下确实是,没有改变,我收回我的傻逼言论
    lihanst
        53
    lihanst  
       13 小时 26 分钟前
    看到这种结果,应该思考为什么要设计一个 ArraySlice ?目的是什么?代价是什么?
    VXF2016
        54
    VXF2016  
       13 小时 26 分钟前
    真离谱
    caiqichang
        55
    caiqichang  
       13 小时 25 分钟前
    确实反直觉
    usVexMownCzar
        56
    usVexMownCzar  
       13 小时 25 分钟前 via iPhone
    没啥好吵的,swift 的 Array 并不是传统概念的数组,真正的数组(连续存储)是最近版本才添加的,InlineArray 。

    话说目前还没看到从源代码来分析上面的代码为什么这么设计🌚
    mizuki9
        57
    mizuki9  
       13 小时 14 分钟前
    好奇葩的设计,好奇葩的行为
    luodan
        58
    luodan  
       13 小时 10 分钟前
    学习了。以后遇到 slice 多留意点。
    FlashEcho
        59
    FlashEcho  
       13 小时 9 分钟前
    @junj2121 #39 c 根本就没有数组切片,得自己手写,天然就会知道这个是一个视图还是拷贝出来一个新的,不参与讨论。c++的数组拷贝是默认拷贝出来一个新的
    whitefable
        60
    whitefable  
       13 小时 0 分钟前
    @junj2121 #39 即使是 C 出身也很反直觉好吧。 要说从指针赋值上去考虑,那 foo 不应该也是指向了 hello[2]么,那此时 foo[2]也是对应 hello[4]才对
    beimenjun
        61
    beimenjun  
    PRO
       12 小时 38 分钟前
    @usVexMownCzar

    苹果关于 ArraySlice 的文档( https://developer.apple.com/documentation/swift/arrayslice )原话是这么说的“Sharing indices between collections and their subsequences is an important part of the design of Swift’s collection algorithms.”

    除了 Array 和 ArraySlice ,甚至 String 和 Substring ,Data 和 Data.SubSequence 都是这样子的。

    感觉最直观的好处就是可以在原对象和切片之间需要频繁调整 index 的步骤简化掉这一步骤。

    比如 Apple 的示例:

    ```
    let absences = [0, 2, 0, 4, 0, 3, 1, 0]

    if let i = absences.firstIndex(where: { $0 > 0 }) { // 1
    let absencesAfterFirst = absences[(i + 1)...] // 2
    if let j = absencesAfterFirst.firstIndex(where: { $0 > 0 }) { // 3
    print("The first day with absences had \(absences[i]).") // 4
    print("The second day with absences had \(absences[j]).")
    }
    }

    // Prints "The first day with absences had 2."
    // Prints "The second day with absences had 4."
    ```
    xz410236056
        62
    xz410236056  
       12 小时 38 分钟前   ❤️ 1
    @ourstars
    @qdwang
    因为你们没看文档,foo 并不是个 array ,而是一个切片(ArraySlice),他的索引并不从 0 开始(取决于你创建方式,大多数共享)。你需要使用特定的函数达到 array 的效果。

    https://developer.apple.com/documentation/swift/arrayslice
    xz410236056
        63
    xz410236056  
       12 小时 37 分钟前
    @fadaixiaohai 关键词现在能搞本书了,恶心的要死。人类根本记不全
    Leeeeex
        64
    Leeeeex  
    PRO
       12 小时 24 分钟前
    @craftsmanship
    也不管原因是啥,也不实践试试 js 有没有同样的问题,反正碰到奇葩问题直接喷 js 就是 zzzq ?
    ikw
        65
    ikw  
       11 小时 59 分钟前
    @PlG5sBkXD1ziLeGB #48 前面保留 index 我都能认为是语言的特性,找到对应的文档并且接受了,但是不修改原数组我就懵了。

    Slice 作为保留原 index 的轻量化视图,修改操作不影响原数组,那修改部分去哪里了?总不能是 Copy on Write 新建了一个 Array 吧,而且这么奇怪的逻辑没有文档强调?

    https://developer.apple.com/documentation/swift/arrayslice
    qdwang
        66
    qdwang  
    OP
       11 小时 52 分钟前 via iPhone
    @wangkun2012324 老哥厉害👍
    coudey
        67
    coudey  
       11 小时 49 分钟前
    有够奇葩的,普通 gpt5 也搞错了。hello 被修改能理解,foo[2]用 hello 的索引真是逆大天
    sankemao
        68
    sankemao  
       11 小时 28 分钟前
    太奇葩了,就你 swift 要搞特殊
    butanediol2d
        69
    butanediol2d  
       11 小时 14 分钟前
    @PlG5sBkXD1ziLeGB COW 生效了,在修改之前,底层使用的 array 是同一块内存,修改时 foo 进行了复制,不是同一块内存了
    yolee599
        70
    yolee599  
       10 小时 37 分钟前 via Android
    @junj2121 #39 错误的,C 语言没有这种反直觉的设计:
    https://onecompiler.com/c/442uqznbg
    wangkun2012324
        71
    wangkun2012324  
       10 小时 24 分钟前   ❤️ 1
    swift 的数组,包括之前吐槽的 string, 一切源于 collection 的设计,collection 的 startIndex 和 endIndex, swift 一致期望用户不使用整数索引,你查看数组的一些排序算法等你会发现根本不是数组的方法,而是 collection 甚至别的 sequence 的各种方法,并且不是所有。
    设计者在做通用的 collection 算法时,https://forums.swift.org/t/rant-indexing-into-arrayslice/14105/14 决定了 Array Slice 这么做。其实我认为这么做之后,array[1]这种风格的写法, 只是 swift 数组只是恰好对的写法,因为 Array.Index 是 Int 。string[1]就不对了。吐槽也是合理的。毕竟是常见的语法,违反直觉的语义
    Azone
        72
    Azone  
       10 小时 22 分钟前
    @PlG5sBkXD1ziLeGB foo[2] 指向的是元素组的索引,不是指向的是原数组。Swift 所有的值类型都是 COW 技术,当你把一个变量赋值给另一个变量并且改变它的值的时候,他们指向的就不是同一块内存了。
    laikicka
        73
    laikicka  
       10 小时 14 分钟前
    @craftsmanship js 的 bug 还少吗
    decken
        74
    decken  
       10 小时 2 分钟前
    语法问题导致的 bug 应该极少吧
    clarkethan
        75
    clarkethan  
       9 小时 32 分钟前
    想了一下,有可能是出于性能考虑吧,减少不必要的深拷贝和内存分配

    再深入想一想,如果我是经常使用 swift 的人,这个设计好像又是可以接受的,语法上这种写法就相当于是一种借用切片,语以上只是记录一下借用范围而已。如果需要在 var foo 的时候直接深拷贝内容,直接用 Array 构造一个新的数据,应该是语言推荐的做法吧。如果有以上心智在前,好像倒不会有太多问题了,不少场合确实能节约一些性能,尤其是资源能耗敏感的场景

    我实际上不写 swift ,仅猜测
    ikw
        76
    ikw  
       9 小时 20 分钟前
    @butanediol2d #69 这样的话,又有几个问题,
    既然设计了 CoW ,那 foo 预期是会作为独立对象存在的,为什么还要用原数组的索引呢?

    CoW 是复制整个 Array 还是复制 slice 对应部分呢?
    foo 有了自己的内存,按说讲他和 hello 已经没什么关系了,这个时候 foo 还要一直用 hello 的索引,似乎也很奇怪吧?
    tiancaixiaoshuai
        77
    tiancaixiaoshuai  
       9 小时 11 分钟前
    直觉是重置索引,我没学过 swift ,如果这是语言特性,也能接受,就像 php 也可以使用 array_slice()里面的 preserve_keys 设为 true 保留原索引,并且这个跟 bug 多也没什么关系吧
    AV1
        78
    AV1  
       9 小时 5 分钟前
    @clarkethan
    感觉你没看懂 OP 表达的,这问题跟“深拷贝”没有任何关系。
    我把他的问题再化简一点,你来猜猜结果:

    var hello = [10, 20, 30, 40, 50, 60]
    var foo = hello[2..<5] // 截取了 hello[2], hello[3], hello[4]

    print(foo[0])
    print(foo[2])

    你猜猜此时 foo[0]和 foo[2]的值分别是多少?🐶
    clarkethan
        79
    clarkethan  
       8 小时 48 分钟前
    @AV1 感觉你没仔细看我的话,哈哈,这就是不同语言的语法设定,如果 swift 中确实是这样的设定,这个语法我个人觉得可以接受,并且确实有一些利好的地方。

    多嘴一句,你说的 “ var foo = hello[2..<5] // 截取了 hello[2], hello[3], hello[4] ”,这里为什么一定是截取呢?你有点先入为主了,还是要先尊重语言本身的基本设定,如果没有深度学习和使用过这门语言,没有相关心智,何止是这一个点,几乎每个语言都有一堆值得吐槽的设定,客观的去看待类似这种东西吧

    转回来,我只是对 swift 中这地方的语法和底层逻辑简单的加以猜测了,没有强依据,本身我也不熟悉 swift ,也没有说这么做很对,只是感觉深入思考一下,我个人表示能接受,仅此而已
    diivL
        80
    diivL  
       8 小时 39 分钟前   ❤️ 1
    @clarkethan #79 你这就像说,只要 swift 设定屎能吃,你就吃屎,并得出一堆吃屎的好处。
    unused
        81
    unused  
       8 小时 28 分钟前   ❤️ 3
    不得不说苹果的东西在提高使用者自适应能力方面是真的牛 B
    butanediol2d
        82
    butanediol2d  
       8 小时 28 分钟前
    @ikw 我个人理解,先不考虑修改的问题,使用原数组的索引有其一定的合理性,这个在 Arrayslice 的文档里也有解释。然后如果 foo 被修改,虽然发生了复制,但 Array 和 Arrayslice 是值语义,所以继续使用原数组的索引。

    CoW 复制的是 slice 对应部分:

    ```swift
    var array = [1, 2, 3, 4, 5]

    var slice = array[1..<4]
    slice.withUnsafeBufferPointer { ptr in
    for i in 0..<4 {
    let val = ptr.baseAddress!.advanced(by: i).pointee
    print(val, terminator: " ")
    }
    print()
    }

    slice[3] = 6

    slice.withUnsafeBufferPointer { ptr in
    for i in 0..<4 {
    let val = ptr.baseAddress!.advanced(by: i).pointee
    print(val, terminator: " ")
    }
    print()
    }
    ```

    输出是
    ```
    2 3 4 5
    2 3 6 xxx
    ```

    xxx 是个“随机”数
    Geon97
        83
    Geon97  
       7 小时 46 分钟前
    远古时期是 c 艹也是这样
    billbur
        84
    billbur  
       7 小时 31 分钟前
    没学过 swift 真不好评价,不知道这种是否会出现在正常项目中。但如果就论这段代码,我很好奇如果使用 foo 的时候偏移值依旧需要使用 hello 的,那我干嘛不直接用 hello ?如果是为了创建一个视图,那么使用这个视图还必须得把起始位置和长度都一并传过去?
    Rickkkkkkk
        85
    Rickkkkkkk  
       7 小时 29 分钟前
    不符合直觉的设计都是烂设计,说破天也是烂设计。
    qdwang
        86
    qdwang  
    OP
       7 小时 17 分钟前
    @billbur 会出现的。比如我有一段二进制数据 A ,我正好需要其中一段数据`B = A[x..<x + size]`,然后我正好要把这段数据最后 4 个字节改为 0 。

    那么按照一般程序员逻辑,用最朴素的写法就是`B[size - 4] = 0; B[size - 3] = 0; B[size - 2] = 0; B[size - 1] = 0`。然后编译不会报错,程序运行也不会报错。只有你检查结果,会发现不对。

    只有认真学过 swift 的人才知道,应该用`startIndex.advanced(by: )`
    butanediol2d
        87
    butanediol2d  
       6 小时 9 分钟前
    @qdwang 你说的有道理,但我感觉可能稍微有点钻牛角尖了。例如你说的这个例子,实际情况这段二进制数据很有可能是 Data 类型,那么就直接用 Data.replaceSubrange(_:with:).subdata(in:) 了,不会直接操作 Array<UInt8>。其次就是,由于对 Array<UInt8> 进行切片后类型是 ArraySlice<UInt8>,但是很有可能你下一步做的操作需要的是一个 Array<UInt8>,所以你大概会选择在切片的时候就直接把它转换成 Array<UInt8>,规避了这个问题。

    所以虽然理论上会有这个坑(例如 Data 的 initializer 就允许 ArraySlice ),但大多数时候用包装好的工具不太会踩。但也可能是我见识的比较少,或许 c/cpp interop 的时候用得多?
    qdwang
        88
    qdwang  
    OP
       5 小时 38 分钟前 via iPhone
    @butanediol2d 巧了,我就是在和 c 交互时候发现这个问题的
    volvo007
        89
    volvo007  
       5 小时 13 分钟前 via iPhone
    @liuhan907 你别说,我 python 跟本不敢说话😂,py 也是 0 打头,因为列表是“可更改对象”,其切片只是引用。如果想切片里改原来的不动,需要 foo = list[slice].copy() 显式拷贝一份
    clarkethan
        90
    clarkethan  
       5 小时 6 分钟前
    @diivL

    我过去写过编译器,也参与过脚本语言的语法/语义设计,清楚语言设计并不是“我不爽就改一下”这么简单:性能约束、开发体验、可读性、兼容性,每一项都要用代价换平衡。

    所以我更习惯先问一句“它为什么这样”,而不是先喊“它怎么敢这样”。发泄情绪很容易,真的做技术的人不会把那当成成就感来源。
    XIVN1987
        91
    XIVN1987  
       4 小时 47 分钟前
    @volvo007

    不需要显示拷贝,,切片是一个新的对象

    In [1]: hello = [10, 20, 30, 40, 50, 60]

    In [2]: foo = hello[2:5]

    In [3]: foo[2] = 0

    In [4]: foo
    Out[4]: [30, 40, 0]

    In [5]: hello
    Out[5]: [10, 20, 30, 40, 50, 60]
    XIVN1987
        92
    XIVN1987  
       4 小时 35 分钟前
    python 里 slicing 得到的是一个新对象,,所有如果你想将 hello 完整复制一份,,可以用 hello[:]

    In [7]: hello = [10, 20, 30, 40, 50, 60]

    In [8]: foo = hello[:]

    In [9]: foo
    Out[9]: [10, 20, 30, 40, 50, 60]

    In [10]: foo == hello
    Out[10]: True

    In [11]: foo is hello
    Out[11]: False
    geminikingfall
        93
    geminikingfall  
       4 小时 28 分钟前
    看来我的直觉还是比较符合苹果设计哲学,难怪别人觉得怪的 Mac 上的特性,我觉得很自然。。。当然,swift 这个设计还是太反人类,没找到第二个这样设计的语言。
    june4
        94
    june4  
       4 小时 9 分钟前
    @Torpedo 问题是,你定义声明的时候是用 null 呢还是 undefined ?还是不嫌麻烦二个都加上?虽然我选择只用 undefined,但很多时候也碰到把 null 转成 undefined 这种操蛋操作,比如 DOM API 基本上都返回 null 而不是 undefined,或有些第三方库选择用 null 。 虽然这事不大,但这是我碰到的唯一不能被 ts 解决的 js 遗留问题,可能会贯穿整个 js 生命周期了。
    onevcat
        95
    onevcat  
       2 小时 37 分钟前
    @wangkun2012324 的理解很正确。在一个 RandomAccessCollection 中,既没有人规定,我们也不应该假设 startIndex 必须等于 0 (实际上我们甚至不应该假设它是 Int )。能写成 foo[2] 只不过是“不幸的巧合”罢了。如果想要表示“序列中位于第三个的元素”,那应该写成:foo[foo.startIndex + 2],而不是一个单纯的 2 。
    bclerdx
        96
    bclerdx  
       20 分钟前
    @Greendays 为了需求,而忽略了能力极限与测试流程,为何呢?
    关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   Solana   ·   1615 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 16:19 · PVG 00:19 · LAX 09:19 · JFK 12:19
    ♥ Do have faith in what you're doing.