In-out 参数不能有默认值

13 Oct 2017 by 晓晨


In-out 参数不能有默认值的解释只有一个,默认值是字面值,in-out 参数不能接受常量和字面值。

以下是自己的一段错误的思路整理,纯属娱乐。

In-out parameters cannot have default values – The Swift Programming Language (Swift 4): Functions

一个参数,“是否被标记为 in-out”,和“是否有默认值”,这两个属性是互斥的。上面的描述可以理解成,


插播(请跳过)

当我想举属性互斥的另一个例子的时候,我想到了“有毒的食物不能吃”,但是我却拆分成了,“食物是否有毒 ”和“食物是否不能吃”,接着想当然地用了另一种反过来说的方法,”不能吃的食物有毒“,显然这是错误的表述,我分析原因是,“食物是否有毒”和“食物是否不能吃”,这两个属性不是互斥关系。

正确的拆分应该是,“食物是否有毒”和“食物是否吃”,这样就能得出,


虽然这二者在使用上没有什么区别,但在理解时,拆分成这两种描述会有不同的理解。

上面这段的理解明显是错的,默认值只是在不提供该参数的时候生效,在提供该参数时没有任何作用,当然不会总把该参数赋值为这个默认值了。

我为什么会有这样的错误?

我是如何发现的?

当我试图把这句话“被标记为 in-out 的参数最终总是这个默认值”表述清楚时,发现表述结果和我心里的感觉不一致。

当我写完上面的话最后补充写出上面的”in-out 给了默认值两种不同的理解“时,我才真正理解了为什么 in-out 参数不能有默认值,因为 in-out 给值的传递的多加了一个反向方向,正常理解时,函数调用者给函数传值,对于有默认值的参数,如果不传值,会用默认值。In-out 函数加的这个反向的传值,是从函数内改变函数传进来的参数,默认值也还可以理解为这个传进来的参数默认会被赋值为这个默认值,尤其当传进来的参数是一个可选值(optional)类型时。

到这里,我发现我需要明确一下默认的定义,

if something happens by default, it happens because you did not do anything to change it – Longman Dictionary of Contemporary English

用到默认值上,就是对这个变量什么都不做的情况下它的值。所以关于 in-out 这个方向值传递的更准确的解释是,如果函数调用者没有对这个参数没有提供值,并且函数内部对这个参数变量什么都没做,那它的值取默认值,当然,这个解释和正常的默认值的解释是冲突的,所以给 in-out 参数提供默认值的解释是有歧义的,所以不能这样做。

重说一遍,给 in-out 参数提供默认值除了会给 in-out 参数传递字面值的问题,还会产生歧义,因为有两种解释,

从调用者角度来说,希望给 in-out 参数提供默认值可能是这样的目的,在我给你传变量的时候,使用变量的值并通过变量把改动传回来,当我不给你传变量的时候,你就用默认值,不需要把改动传回来,但对于函数实现来说,没有办法知道这个参数是变量还是字面值。

总结,写出来才能发现自己错了,才有分析错误原因的可能。这里,根本原因是对默认的理解。