【问题标题】:Swift: How to store a reference to Double, IntSwift:如何存储对 Double、Int 的引用
【发布时间】:2015-12-13 23:00:19
【问题描述】:

我想在 Swift 中存储对原始类型 (Double, Int) 的引用,以便我更改一个变量,也更改另一个变量。这是一个例子:

class MyClass {
    var value: Double?
}

var myValue = 1.0

var instance = MyClass()
instance.value = myValue    // <-- how to set a reference?

myValue = 2.0               // => I want instance.value to change to 2.0
instance.value = 3.0        // => I want myValue to change to 3.0

这可能吗?

【问题讨论】:

  • 只是不要期望 Swift 能像这样工作。 Swift 没有像 C++ 那样的引用(即使那样这也是.. 可疑的);虽然 Swift 中有 pointer support 这仍然是 错误 编写 Swift 代码的方式;相反,容器“MyClass”实例通过可变性和对象共享语义充当“引用”。如果您需要另一个“引用”分隔,请创建另一个包装器类型。
  • 请参阅stackoverflow.com/questions/26436932/…,了解如何创建通用的“Box”或“Holder”或“Ref”类型。
  • @user2864740:谢谢,我知道指针是一种不好的做法(直接访问内存),包装器类型可能是最好的解决方案。

标签: swift pass-by-reference swift2


【解决方案1】:

你可以使用类持有者:

class Ref<T> {
  var value: T

  init(_ value: T) {
    self.value = value
  }
}

或尝试阅读有关 In-Out 参数的信息,也许它可以以某种方式帮助您:

In-Out Parameters

变量参数,如上所述,只能在 函数本身。如果你想让一个函数修改一个参数的 值,并且您希望这些更改在函数调用后持续存在 已结束,请将该参数定义为 in-out 参数。

通过将 inout 关键字放在 开始其参数定义。输入输出参数有一个值 传递给函数,由函数修改,并且是 从函数传回以替换原始值。

您只能将变量作为输入输出参数的参数传递。 您不能将常量或文字值作为参数传递,因为 常量和文字不能被修改。您放置一个 & 号 (&) 当您将变量作为参数传递给变量时,直接在变量名称之前 一个 inout 参数,表示它可以由 函数。

func swapTwoInts(inout a: Int, inout _ b: Int) {
    let temporaryA = a
    a = b
    b = temporaryA
}

var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt, &anotherInt)
print("someInt is now \(someInt), and anotherInt is now \(anotherInt)")
// prints "someInt is now 107, and anotherInt is now 3"

【讨论】:

  • 感谢包装类型的示例。 inout 参数对我来说不是一个选项,因为我想绑定以后可以读写的类成员变量。
【解决方案2】:

我能想到的最接近 Swift 的东西是 inout 变量。它们在 Swift 中被允许作为构造函数参数(但将它们保存到变量会阻止它们工作):

class Demo {
    var value: Double

    init(inout value: Double) {
        value++
        self.value = value
    }
}

var value = 1.0
let demo = Demo(value: &value)
print(value) // 2.0

demo.value++
print(value) // 2.0

因此,我不相信您想要的语法是可能的。但是,如果您可以重新解决问题,也许inout 参数可以替代。

【讨论】:

    【解决方案3】:

    我用这个:

    @propertyWrapper public struct Inout<T> {
        public init(wrappedValue: T) {
            storage = .init(value: wrappedValue)
        }
        
        private let storage: Storage
        
        public var wrappedValue: T {
            nonmutating get { storage.value }
            nonmutating set { storage.value = newValue }
        }
        
        private class Storage {
            init(value: T) {
                self.value = value
            }
            
            var value: T
        }
    }
    

    例子:

    struct Example { 
        init(value: Inout<Int>) { 
            _value = value
        }
        
        @Inout var value: Int
        
        func performAction() { 
            value += 19
        }
    }
    let value = Inout(wrappedValue: 50)
    let example = Example(value: value)
    example.performAction()
    print(value.wrappedValue) // 69
    

    【讨论】:

      猜你喜欢
      • 2015-05-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-16
      • 2014-10-22
      • 2011-02-25
      • 1970-01-01
      相关资源
      最近更新 更多