![](/img/trans.png)
[英]How do I return functions with inout parameters and a return type of Void in Swift?
[英]Swift/iOS: How to use inout parameters in functions with AnyObject/Any or Pointers
我正在尝试编写一个函数,它接受一个变量指针和一个描述符/键,并为变量设置一个新值。 理想情况下,指针应该是对象或基元,但我也可以使用单独的函数(或其他参数)。 在我的代码中,我也使用键从数据库中检索新值,但在下面的示例中,我使用虚拟值对其进行了简化,以便可以在操场中轻松使用:
import UIKit
func setValue(inout object: AnyObject, key: String) {
switch key {
case "String":
object = "A String"
case "UIColor":
object = UIColor.whiteColor()
case "Bool":
object = true
default:
println("Unhandled key: \(key)")
}
}
var string: String = "Default String"
var color: UIColor = UIColor.blackColor()
var bool: Bool = false
setValue(&string, "String")
setValue(&color, "UIColor")
setValue(&bool, "Bool")
我收到以下错误:
“无法使用类型'的参数列表调用'setValue'(inout String,key String)'”
我知道我在这里混合了对象和原始。 我也尝试将其分解并将它们分成两个函数,但即便失败:
func setValue(inout object: AnyObject, key: String) {
switch key {
case "UIColor":
object = UIColor.whiteColor()
default:
println("Unhandled key: \(key)")
}
}
var color: UIColor = UIColor.blackColor()
setValue(&color, "UIColor")
这也给出了同样的错误:
“无法使用类型'的参数列表调用'setValue'(inout UIColor,key String)'”
如果我将'AnyObject'更改为'UIColor'它可以工作,但函数的重点是,它需要任何变量类型或至少任何对象类型(我会使用“Any”为基元编写第二个函数然后添加另一个参数)
在Objective-C中我使用指针,将方法转移到Swift也不起作用,结果相同:
func setValue(object: UnsafeMutablePointer<AnyObject>, key: String) {
switch key {
case "String":
object.memory = "A String"
case "UIColor":
object.memory = UIColor.whiteColor()
case "Bool":
object.memory = true
default:
println("Unhandled key: \(key)")
}
}
有没有人知道我在这里缺少什么? 任何帮助深表感谢!
谢谢!
更好的是你可以创建如下的通用方法:
func setValue<T>(inout object:T, key: String) {
switch key {
case "String":
object = ("A String" as? T)!
case "UIColor":
object = (UIColor.whiteColor() as? T)!
case "Bool":
object = (true as? T)!
default:
println("Unhandled key: \(key)")
}
}
呼叫将是这样的:
setValue(&string, key: "String")
setValue(&color, key: "UIColor")
setValue(&bool, key: "Bool")
希望能帮助到你!
正确的方法是使用重载,让编译器在编译时选择适当的代码位,而不是在运行时关闭字符串:
func setValue(inout object: String) {
object = "A String"
}
func setValue(inout object: UIColor) {
object = UIColor.whiteColor()
}
func setValue(inout object: Bool) {
object = true
}
func setValue(inout object: Any) {
println("Unhandled key: \(key)")
}
当你有一个Any
并希望向函数指示Any
包含什么类型时,这种方法不起作用...但在这种情况下,你遇到问题的原因是编译器确实知道类型是什么,所以你可以利用这一点。
- 使用Any而不是AnyObject来覆盖值类型和结构。
- 在调用方法之前,您可能需要转换为Any。
例:
func swapAny( inout obj1: Any, inout obj2: Any )
{
let temp = obj1
obj1 = obj2
obj2 = temp
}
使用:
var fooString: Any = "Foo"
var barString: Any = "Bar"
swapAny(&fooString, obj2: &barString)
println(fooString)//prints "Bar"
当您将类转换为协议时,您最终会得到一个不可变引用,该引用无法在inout函数参数中使用。 所以你可以:
-
protocol IPositional{
func setPosition(position:CGPoint)
}
extension IPositional{
var positional:IPositional {get{return self as IPositional}set{}}
}
class A:IPositional{
var position:CGPoint = CGPoint()
func setPosition(position:CGPoint){
self.position = position
}
}
func test(inout positional:IPositional){
positional.setPosition(CGPointMake(10,10))
}
var a = A()
test(&a.positional)
a.position//output: (10.0, 10.0)
结论:
这样做的好处是:你现在可以为实现IPositional的所有类都有一个“inout方法”但是我建议选择2。(不使用inout)
对象的类型应该与参数的类型匹配,包括AnyObject
:
func setValue(inout object: AnyObject, key: String) {
switch key {
case "String":
object = "A String"
case "UIColor":
object = UIColor.whiteColor()
case "Bool":
object = true
default:
print("Unhandled key: \(key)")
}
}
var string: AnyObject = "Default String"
var color: AnyObject = UIColor.blackColor()
var bool: AnyObject = false
setValue(&string, key: "String")
setValue(&color, key: "UIColor")
setValue(&bool, key: "Bool")
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.