Swift 为什么设计 inout 关键字? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
iOS 开发实用技术导航
NSHipster 中文版
http://nshipster.cn/
cocos2d 开源 2D 游戏引擎
http://www.cocos2d-iphone.org/
CocoaPods
http://cocoapods.org/
Google Analytics for Mobile 统计解决方案
http://code.google.com/mobile/analytics/
WWDC
https://developer.apple.com/wwdc/
Design Guides and Resources
https://developer.apple.com/design/
Transcripts of WWDC sessions
http://asciiwwdc.com
Cocoa with Love
http://cocoawithlove.com/
Cocoa Dev Central
http://cocoadevcentral.com/
NSHipster
http://nshipster.com/
Style Guides
Google Objective-C Style Guide
NYTimes Objective-C Style Guide
Useful Tools and Services
Charles Web Debugging Proxy
Smore
fffang
V2EX    iDev

Swift 为什么设计 inout 关键字?

  •  
  •   fffang 2021-05-08 17:19:18 +08:00 4625 次点击
    这是一个创建于 1699 天前的主题,其中的信息可能已经有所发展或是发生改变。

    从语言设计的角度上看,有什么必要性么?如果像 OC 那样会发生什么情况?

    8 条回复    2021-05-09 12:32:16 +08:00
    Elethom
        1
    Elethom  
       2021-05-08 17:31:17 +08:00 via iPhone
    OC 也可以丢个 & 进去啊,你这是两个语言都没入门吗,先学会一个再学另一个吧。
    zjw7sky
        2
    zjw7sky  
       2021-05-08 17:36:43 +08:00
    传值、传址
    fffang
        3
    fffang  
    OP
       2021-05-08 17:37:43 +08:00
    @Elethom OC 是可以的。
    可是 OC 中参数 Array 是可以 append 元素的,而 Swift 好像不可以?
    MrKrabs
        4
    MrKrabs  
       2021-05-08 17:46:46 +08:00
    value 和 reference 不一样
    superpeaser
        5
    superpeaser  
       2021-05-08 17:51:23 +08:00
    @fffang OC 的参数 array 传的可变数组的地址
    YYYeung
        6
    YYYeung  
       2021-05-09 00:16:05 +08:00
    Swift 的 inout 表示操作的是指针

    而有一些数据结构,如数组,在 Swift 中是值传递,在 OC 中是引用传递,这会发生什么事?

    在 OC 中,当将一个数组作为一个参数传到另一个函数或方法中,并在该函数体或方法体中,对这个数组 append 一个元素,是没有什么反“直觉”的事发生,一切都很自然

    而在 Swift 中,实际上是 append 到了一个新数组,原来的数组是没有改变的,此时,要实现 OC 的“直觉”效果,就需要用到 inout 了
    0x00ZhouJialei
        7
    0x00ZhouJialei  
       2021-05-09 03:33:06 +08:00
    先说动机 , 引用自 https://docs.swift.org/swift-book/LanguageGuide/Functions.html In-Out Parameters 章节:
    Function parameters are constants by default. Trying to change the value of a function parameter from within the body of that function results in a compile-time error. This means that you can’t change the value of a parameter by mistake. If you want a function to modify a parameter’s value, and you want those changes to persist after the function call has ended, define that parameter as an in-out parameter instead.

    再说行为, 引用自 https://docs.swift.org/swift-book/ReferenceManual/Declarations.html#ID545:
    In-out parameters are passed as follows:
    1. When the function is called, the value of the argument is copied.
    2. In the body of the function, the copy is modified.
    3.When the function returns, the copy’s value is assigned to the original argument.
    This behavior is known as copy-in copy-out or call by value result. For example, when a computed property or a property with observers is passed as an in-out parameter, its getter is called as part of the function call and its setter is called as part of the function return.

    多说几句,编译器有可能会把 inout 优化为所谓的传址(call-by-reference),但是官方特意指出开发者们不能依赖这个行为:
    As an optimization, when the argument is a value stored at a physical address in memory, the same memory location is used both inside and outside the function body. The optimized behavior is known as call by reference;
    Write your code using the model given by copy-in copy-out, without depending on the call-by-reference optimization, so that it behaves correctly with or without the optimization

    不严谨的验证方式是,传一个带有 willSet 或者 didSet 的变量到一个 function 的 inout 参数内,就算在 function 内不改变值,willSet 或者 didSet 也会触发
    iOCZ
        8
    iOCZ  
       2021-05-09 12:32:16 +08:00
    不是必须,但是便利吧。常见的是要返回操作成功与否,还要返回处理结果,返回元组当然可以,但是不那么方便。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     945 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 24ms UTC 23:41 PVG 07:41 LAX 15:41 JFK 18:41
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86