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

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

  •  
  •   qdwang · 3 天前 · 11867 次点击

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

    109 条回复    2025-10-28 18:48:00 +08:00
    1  2  
    ourstars
        1
    ourstars  
       3 天前   ❤️ 16
    直觉理解是[30,40,0],但是运行之后是[0,40,50]。
    foo 用的是 hello 的索引范围造成了[0,40,50]的结果。
    qdwang
        2
    qdwang  
    OP
       3 天前 via iPhone
    @ourstars 对,swift 设计了这个反程序员直觉的语义。导致你去问 ai ,也有一大堆 ai 会回答错误。
    TianDogK48
        3
    TianDogK48  
       3 天前 via iPhone   ❤️ 1
    目测这个语法不常用,所以问题应该不大; go 里面 slice 扩容,也有坑,但是目测 go 的 slice 很少用,都是直接 make
    raycool
        4
    raycool  
       3 天前
    看来都是 slice 的不同理解导致的。
    smlcgx
        5
    smlcgx  
       3 天前 via iPhone
    这样看起来 swift 更偏向自然语言一点,几就是几
    butanediol2d
        6
    butanediol2d  
       2 天前
    hello 是 Array<Int>
    foo 是 ArraySlice<Int>
    craftsmanship
        7
    craftsmanship  
       2 天前 via Android
    如此说来 JS 早先那些垃圾设计可能导致的 bug 只会更多。。
    xuejianxianzun
        8
    xuejianxianzun  
       2 天前
    @craftsmanship 怎么又扯到 js 了,js 在这个场景里没有反直觉的行为。
    hash
        9
    hash  
       2 天前   ❤️ 1
    系统层核心实现是一坨屎,与语言设计无关
    Building
        10
    Building  
       2 天前
    都按直觉那不同语言反人类的语法简直不要太多,当然不影响 Swift String 的设计才是最为逆天的东西
    cpstar
        11
    cpstar  
       2 天前
    @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  
       2 天前   ❤️ 1
    和语言关系不大的,既然做了开发掌握这个语言的语法是基本要求。Bug 多只是需求超过了能力,不得不赶工和减少测试流程造成的。
    Lin0936
        13
    Lin0936  
       2 天前
    再逆天的语言也该经过测试啊
    june4
        14
    june4  
       2 天前
    @craftsmanship js 真没有啥绕不过去的垃圾设计,特别是 ts 上身后,底子非常干净纯洁,现在只有一个日常使用我觉得不爽,就是搞出二个 null/undefined 类型。
    xiangyuecn
        15
    xiangyuecn  
       2 天前
    苹果拉的屎就是香,没啥毛病 能咽下去的
    freeloop1
        16
    freeloop1  
       2 天前
    那个 foreach 的语法我是最蚌埠住的,我总感觉是少写了括号啥的,太难受了。
    a33291
        17
    a33291  
       2 天前
    foo 是 hello 的视图吧? 现在很多语言/库都提供这种东西,减少 copy,不过大部分是只读的比较合理
    cookii
        18
    cookii  
       2 天前 via Android
    @a33291 视图通常只读会好一点
    fadaixiaohai
        19
    fadaixiaohai  
       2 天前
    从 swift6 开始越来越复杂,关键词越搞越多,问题是有些关键词编译器都支持不太好,搞不好就容易 crash ,对新人也不太友好
    PlG5sBkXD1ziLeGB
        20
    PlG5sBkXD1ziLeGB  
       2 天前 via iPhone
    swift 的语法真是丑到爆,OC 的语法虽然跟裹脚布一样长,但是可读性非常强
    deplives
        21
    deplives  
       2 天前
    kfpenn
        22
    kfpenn  
       2 天前
    liuhan907
        23
    liuhan907  
       2 天前   ❤️ 1
    这个输出 [0, 40, 50] 不才是符合直觉的?
    cpper
        24
    cpper  
       2 天前
    每个语言有每个语言的用法,不要陷入奇巧淫技的细节中
    liuhan907
        25
    liuhan907  
       2 天前   ❤️ 2
    哦,大意了,foo[2] 啊。那这是傻逼设计,我看的不够仔细啊 -_-
    IDAEngine
        26
    IDAEngine  
       2 天前
    这是一个关于 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  
       2 天前 via iPhone   ❤️ 1
    @cpstar 主楼的代码应该是对标的 js 的 Array.slice(2,5)
    ccnoobs
        28
    ccnoobs  
       2 天前
    @IDAEngine "在 foo 中,索引 2 对应的值是 30 。" 不知道你怎么想的
    yuanxing008
        29
    yuanxing008  
       2 天前
    可能 go 和 python 写的太久了 我的第一直觉就是[0,40,50]

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

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

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

    话说目前还没看到从源代码来分析上面的代码为什么这么设计🌚
    mizuki9
        57
    mizuki9  
       2 天前
    好奇葩的设计,好奇葩的行为
    luodan
        58
    luodan  
       2 天前
    学习了。以后遇到 slice 多留意点。
    FlashEcho
        59
    FlashEcho  
       2 天前
    @junj2121 #39 c 根本就没有数组切片,得自己手写,天然就会知道这个是一个视图还是拷贝出来一个新的,不参与讨论。c++的数组拷贝是默认拷贝出来一个新的
    whitefable
        60
    whitefable  
       2 天前
    @junj2121 #39 即使是 C 出身也很反直觉好吧。 要说从指针赋值上去考虑,那 foo 不应该也是指向了 hello[2]么,那此时 foo[2]也是对应 hello[4]才对
    beimenjun
        61
    beimenjun  
    PRO
       2 天前
    @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  
       2 天前   ❤️ 1
    @ourstars
    @qdwang
    因为你们没看文档,foo 并不是个 array ,而是一个切片(ArraySlice),他的索引并不从 0 开始(取决于你创建方式,大多数共享)。你需要使用特定的函数达到 array 的效果。

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

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

    https://developer.apple.com/documentation/swift/arrayslice
    qdwang
        66
    qdwang  
    OP
       2 天前 via iPhone
    @wangkun2012324 老哥厉害👍
    coudey
        67
    coudey  
       2 天前
    有够奇葩的,普通 gpt5 也搞错了。hello 被修改能理解,foo[2]用 hello 的索引真是逆大天
    sankemao
        68
    sankemao  
       2 天前
    太奇葩了,就你 swift 要搞特殊
    butanediol2d
        69
    butanediol2d  
       2 天前
    @PlG5sBkXD1ziLeGB COW 生效了,在修改之前,底层使用的 array 是同一块内存,修改时 foo 进行了复制,不是同一块内存了
    yolee599
        70
    yolee599  
       2 天前 via Android
    @junj2121 #39 错误的,C 语言没有这种反直觉的设计:
    https://onecompiler.com/c/442uqznbg
    wangkun2012324
        71
    wangkun2012324  
       2 天前   ❤️ 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  
       2 天前
    @PlG5sBkXD1ziLeGB foo[2] 指向的是元素组的索引,不是指向的是原数组。Swift 所有的值类型都是 COW 技术,当你把一个变量赋值给另一个变量并且改变它的值的时候,他们指向的就不是同一块内存了。
    laikicka
        73
    laikicka  
       2 天前
    @craftsmanship js 的 bug 还少吗
    decken
        74
    decken  
       2 天前
    语法问题导致的 bug 应该极少吧
    clarkethan
        75
    clarkethan  
       2 天前
    想了一下,有可能是出于性能考虑吧,减少不必要的深拷贝和内存分配

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

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

    CoW 是复制整个 Array 还是复制 slice 对应部分呢?
    foo 有了自己的内存,按说讲他和 hello 已经没什么关系了,这个时候 foo 还要一直用 hello 的索引,似乎也很奇怪吧?
    tiancaixiaoshuai
        77
    tiancaixiaoshuai  
       2 天前
    直觉是重置索引,我没学过 swift ,如果这是语言特性,也能接受,就像 php 也可以使用 array_slice()里面的 preserve_keys 设为 true 保留原索引,并且这个跟 bug 多也没什么关系吧
    AV1
        78
    AV1  
       2 天前
    @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  
       2 天前
    @AV1 感觉你没仔细看我的话,哈哈,这就是不同语言的语法设定,如果 swift 中确实是这样的设定,这个语法我个人觉得可以接受,并且确实有一些利好的地方。

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

    转回来,我只是对 swift 中这地方的语法和底层逻辑简单的加以猜测了,没有强依据,本身我也不熟悉 swift ,也没有说这么做很对,只是感觉深入思考一下,我个人表示能接受,仅此而已
    diivL
        80
    diivL  
       2 天前   ❤️ 1
    @clarkethan #79 你这就像说,只要 swift 设定屎能吃,你就吃屎,并得出一堆吃屎的好处。
    unused
        81
    unused  
       2 天前   ❤️ 4
    不得不说苹果的东西在提高使用者自适应能力方面是真的牛 B
    butanediol2d
        82
    butanediol2d  
       2 天前   ❤️ 1
    @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  
       2 天前
    远古时期是 c 艹也是这样
    billbur
        84
    billbur  
       2 天前
    没学过 swift 真不好评价,不知道这种是否会出现在正常项目中。但如果就论这段代码,我很好奇如果使用 foo 的时候偏移值依旧需要使用 hello 的,那我干嘛不直接用 hello ?如果是为了创建一个视图,那么使用这个视图还必须得把起始位置和长度都一并传过去?
    Rickkkkkkk
        85
    Rickkkkkkk  
       2 天前   ❤️ 1
    不符合直觉的设计都是烂设计,说破天也是烂设计。
    qdwang
        86
    qdwang  
    OP
       2 天前
    @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  
       2 天前
    @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
       2 天前 via iPhone
    @butanediol2d 巧了,我就是在和 c 交互时候发现这个问题的
    volvo007
        89
    volvo007  
       2 天前 via iPhone
    @liuhan907 你别说,我 python 跟本不敢说话😂,py 也是 0 打头,因为列表是“可更改对象”,其切片只是引用。如果想切片里改原来的不动,需要 foo = list[slice].copy() 显式拷贝一份
    clarkethan
        90
    clarkethan  
       2 天前
    @diivL

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

    所以我更习惯先问一句“它为什么这样”,而不是先喊“它怎么敢这样”。发泄情绪很容易,真的做技术的人不会把那当成成就感来源。
    XIVN1987
        91
    XIVN1987  
       2 天前
    @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  
       2 天前
    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  
       2 天前
    看来我的直觉还是比较符合苹果设计哲学,难怪别人觉得怪的 Mac 上的特性,我觉得很自然。。。当然,swift 这个设计还是太反人类,没找到第二个这样设计的语言。
    june4
        94
    june4  
       2 天前
    @Torpedo 问题是,你定义声明的时候是用 null 呢还是 undefined ?还是不嫌麻烦二个都加上?虽然我选择只用 undefined,但很多时候也碰到把 null 转成 undefined 这种操蛋操作,比如 DOM API 基本上都返回 null 而不是 undefined,或有些第三方库选择用 null 。 虽然这事不大,但这是我碰到的唯一不能被 ts 解决的 js 遗留问题,可能会贯穿整个 js 生命周期了。
    onevcat
        95
    onevcat  
       2 天前
    @wangkun2012324 的理解很正确。在一个 RandomAccessCollection 中,既没有人规定,我们也不应该假设 startIndex 必须等于 0 (实际上我们甚至不应该假设它是 Int )。能写成 foo[2] 只不过是“不幸的巧合”罢了。如果想要表示“序列中位于第三个的元素”,那应该写成:foo[foo.startIndex + 2],而不是一个单纯的 2 。
    bclerdx
        96
    bclerdx  
       2 天前
    @Greendays 为了需求,而忽略了能力极限与测试流程,为何呢?
    ikw
        97
    ikw  
       2 天前
    @butanediol2d #82 非常感谢帮忙做解答,CoW 复制的验证部分很有帮助。

    使用原数组索引,或者 foo 有 CoW ,单独来说确实我也觉得有一定合理性,但是这俩放一起就感觉有点别扭,不太理解设计者是怎么考量的。
    MrKrabs
        98
    MrKrabs  
       1 天前
    但我不会教你的
    diivL
        99
    diivL  
       1 天前
    @clarkethan 幸亏你设计的屎没有流行,不然大伙都得吃你拉的屎,还要帮你找吃屎的好处。
    rrfeng
        100
    rrfeng  
       1 天前
    我想问,foo[0] 会怎么样?
    1  2  
    关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   Solana   ·   1296 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 93ms · UTC 17:13 · PVG 01:13 · LAX 10:13 · JFK 13:13
    ♥ Do have faith in what you're doing.