Swift可选inout参数和nil
Swift中的函数是否可以有一个Swift可选inout参数和nil,swift,optional,Swift,Optional,Swift中的函数是否可以有一个可选的inout参数?我正在尝试这样做: func testFunc( inout optionalParam: MyClass? ) { if optionalParam { ... } } …但当我试图调用它并传递nil时,它给了我一个奇怪的编译错误: Type 'inout MyClass?' does not conform to protocol 'NilLiteralConvertible' 我不明白为什么我的类在声
可选的inout
参数?我正在尝试这样做:
func testFunc( inout optionalParam: MyClass? ) {
if optionalParam {
...
}
}
…但当我试图调用它并传递nil
时,它给了我一个奇怪的编译错误:
Type 'inout MyClass?' does not conform to protocol 'NilLiteralConvertible'
我不明白为什么我的类在声明为可选时必须遵守某些特殊协议。它不会编译,因为函数需要引用,但您传递了nil
。这个问题与选择无关
通过使用inout
声明参数,意味着您将在函数体内部为其赋值。它如何将值赋给nil
你需要像这样称呼它
var a : MyClass? = nil
testFunc(&a) // value of a can be changed inside the function
如果你知道C++,这是C++代码的版本,没有可选的
struct MyClass {};
void testFunc(MyClass &p) {}
int main () { testFunc(nullptr); }
您收到了这个错误消息
main.cpp:6:6: note: candidate function not viable: no known conversion from 'nullptr_t' to 'MyClass &' for 1st argument
这相当于你所得到的(但更容易理解)这是可能的,而且可能与之有关。()
可选项可以具有nil值,但不应为nil。因此,如果您只是不将其传递给函数或传递类型为MyClass的变量,那么这个可选选项就可以工作了?值为零。就像布莱恩州
编写函数时,它必须有一个默认值作为可选参数,如下所示:
func testFunc(inout optionalParam:MyClass?={var nilRef:MyClass?;return &nilRef}()) {
if optionalParam != nil {
...
}
}
请注意,如果optionalParam{…}
更改为如果optionalParam!=无{…}
如果optionalParam?!=nil
,作为uwrapping,optionalParam?
在optionalParam==nil
时失败~注意,var a:MyClass?
在赋值之前的值为nil
调用是,testFunc(可选参数:&a)
或testFunc()
,但决不testFunc(nil)
我想你可能会把两个不同的概念交织在一起,因为它们有相似的名称、可选参数和可选项。Optionals是具有扩展nil条件的变量。可选参数是可选的功能参数
进一步阅读。苹果正试图将措辞从可选参数改为“带有默认值的参数”。不幸的是,他们没有在这些新的可选内容中包含可选参数行为。如果零个选项在打开时失败,那么将其作为选项传递有什么意义。如果可以在打开包装之前传递,那么它可能会更深入地理解这个可选内容的核心。。。薛定谔猫的确切含义是:
只能将变量作为输入输出参数的参数传递。
不能将常量或文字值作为参数传递,因为
无法修改常量和文字。您可以放置一个符号(&)
当您将变量作为参数传递给
一个inout参数,指示可以由
功能
但是请注意,根据@gnasher的注释(编辑),如果您打算或希望将实例替换为另一个实例,而不仅仅是修改原始实例,则只需将类作为inout(也称为引用)传递。文件中涉及这一点的段落是:
输入输出参数
如上所述,可变参数只能在
函数本身。如果希望函数修改参数的
值,并且您希望这些更改在函数调用后保持不变
结束后,将该参数定义为输入输出参数
这里有三个测试涵盖了var和inout的使用
class Bar : Printable {
var value = 1
init(_ value:Int) { self.value = value }
var description:String { return "Bar is: \(value)" }
}
let bar = Bar(1)
func changeBarWithoutInoutSinceBarIsAClassYaySwift(b:Bar) { b.value = 2 }
changeBarWithoutInoutSinceBarIsAClassYaySwift(bar)
println("after: \(bar)") // 2
var bar2 = Bar(0)
func tryToReplaceLocalBarWithoutInout(var b:Bar) { b = Bar(99) }
tryToReplaceLocalBarWithoutInout(bar2)
println("after: \(bar2)") // 0
var bar3 = Bar(0)
func replaceClassInstanceViaInout(inout b:Bar) { b = Bar(99) }
replaceClassInstanceViaInout(&bar3)
println("after: \(bar3)") // 99
实际上@devios1需要的是“可选指针”。 但是我不在我的班上吗?表示“指向可选项的指针”。 以下内容应适用于Swift 4
class MyClass {
// func foo() {}
}
func testFunc(_ optionalParam: UnsafeMutablePointer<MyClass>? ) {
if let optionalParam = optionalParam {
// optionalParam.pointee.foo()
// optionalParam.pointee = MyClass()
}
}
testFunc(nil)
var myClass = MyClass()
testFunc(&myClass)
class-MyClass{
//func foo(){}
}
func testFunc(uOptionalParam:UnsafeMutablePointer?){
如果让optionalParam=optionalParam{
//optionalParam.pointee.foo()
//optionalParam.pointee=MyClass()
}
}
testFunc(无)
var myClass=myClass()
testFunc(&myClass)
所以我猜答案是否定的。我确信这在Objective-C中是可能的。哦,好吧。@chaiguy也许你可以尝试像自动释放指针那样的指针。但是在我看来,这是丑陋的。@devios在客观条件下肯定是可能的。这就是为什么nils是有毒的。Swift的例子很好,并且使之成为可能。我忘了在try块中提到常见的流行语是,如果a==nil{a=MyClass();}
,不幸的是,这似乎没有在Swift 3.0中为我在Xcode上编译:我得到错误“&”只能立即出现在调用参数列表中
,实际上,inout对引用(类)的作用是一样的。除了结构的值之外,结构的所有元素都是引用,而引用的值只是引用本身。如果您传递NSMutableString thisString,则无法将其更改为NSMutableString thatString,除非您使用var或inout。更改字符并不会更改引用。@gnasher,谢谢您的发布,这样更有意义。我相应地更新了我的答案。