学习Swift - inout函数 - 为什么要修改全局变量值?

时间:2016-11-07 00:52:30

标签: javascript swift

我来自Javascript背景,我正在寻找一些关于Swift的清晰度。

在Javascript中,函数的参数仅存在于该函数的范围内。例如,我可以毫无问题地做到这一点。

function greet(name) {
 name = "randomDude";
 return name
}

greet("Barry");

这是有效的,因为参数名称仅存在于greet函数的范围内。所以我可以改变名字的价值。

但是,在Swift中,我不能这样做:

func greet(name: String) {
   name = "Ardvark"
   print(name)
}

greet(name: "Drew")

解决方案是将其更改为“inout”函数,该函数只能采用变量,即:

func greet(name: inout String) {
       name = "Ardvark"
       print(name)
    }

var name = "Drew"    
greet(name: name)

然而,当我这样做时,它实际上改变了var name的值。这意味着inout函数不会仅修改函数范围内PARAMETER的值,而是修改全局变量。

这是我必须接受的吗?是否有理由修改全局变量?你如何只修改函数greet中的变量'name'?

由于

3 个答案:

答案 0 :(得分:5)

第二个代码块(第一个Swift示例)阻止您更改name的值的原因是因为在Swift 3中,所有参数都是常量。换句话说,它们基本上都是用let声明的。

想象一下你的第一个Swift示例:

func greet(let name: String) {
   name = "Ardvark"
   print(name)
}

显然,你并没有真正放置let,但这会帮助你记住参数是不可变的。这可以防止您错误地更改值。如果要在函数内部更改它,请使用新变量:

func greet(name: String) {
   let anotherName = "Ardvark"
   print(anotherName)
}

使用inout更改参数"删除let"并允许您更改调用函数时使用的原始变量。

  

您如何仅修改变量' name'在函数内部问候?

你不在Swift 3中。参数是不可变的。将其分配给函数内的新变量。

答案 1 :(得分:2)

func greet(name: String) {}函数中name是一个常量,实际上它看起来像func greet(let name: String) {},因此您无法对其进行修改。让我们添加一个新变量并为其赋值name

func greet(name: String) {
    var newName = name
    newName = "Ardvark"
    print(newName)
}

答案 2 :(得分:0)

阅读一些Swift文档。得出两个结论。

(1)默认情况下,Swift中的参数是CONSTANTS,因此就好像在参数之前有一个let关键字。函数内部的含义,参数值不能更改,否则将引发错误。

(2)将您的功能更改为'inout'功能会改变一些事情。首先,它删除了'let'约束。其次,当您将参数传入inout参数时,它被称为copy-in,copy-out。参数的值被复制到内存中,通过函数传递,在函数中修改,新值被赋值给作为参数传递的原始变量。

如果您考虑这些,这是两种不同类型的功能。换句话说,没有Javascript中的功能,您只需在函数范围内修改参数值即可。

由于:

参数是CONSTANT(默认情况下),

... OR

您正在使用inout函数,在这种情况下,参数是一个变量而不是常量,但该参数仅用于将参数的原始值“传递”到可以修改的函数中,然后将其作为新值释放回内存中的原始变量占位符。

换句话说......在Swift中没有办法(我知道)只修改一个参数的值INSIDE它的函数范围。默认情况下禁止这样做,因为参数是常量,或者您正在使用inout函数,它不会仅修改函数内部的参数值...它正在修改GLOBAL命名空间的值。