【问题标题】:What are 'get' and 'set' in Swift?Swift 中的“获取”和“设置”是什么?
【发布时间】:2014-07-11 13:48:42
【问题描述】:

我正在学习 Swift,我正在阅读 Apple 的 The Swift Programming Language。我没有任何 Objective-C 背景(只有 PHP、JavaScript 等,但没有 Objective-C)。

在第 24-25 页,我看到了这段代码:

//...Class definition stuff...

var perimeter: Double {
    get {
        return 3.0 * sideLength
    }
    set {
        sideLength = newValue / 3.0
    }
}

//...Class continues...

这部分在书中没有具体说明,我不明白这些是干什么用的。

什么是getset

【问题讨论】:

  • 您是否阅读了关于 getter/setter 的第 21 页。此外,前 30 pgs 左右是 Swift 的tour,而不是完整的文档。
  • 如果你学过 C++,你可以将这些东西与类的 getter 和 setter 成员函数关联起来

标签: swift accessor


【解决方案1】:

类中变量的获取和设置是指检索(“获取”)或更改(“设置”)它们的内容。

考虑类family 的变量members。当然,这个变量需要是一个整数,因为一个家庭永远不可能由两个人组成。

因此,您可能会继续定义 members 变量,如下所示:

class family {
  var members:Int
}

然而,这将使使用这个类的人可以将家庭成员的数量设置为 0 或 1。而且由于不存在 1 或 0 的家庭,这是非常不幸的。

这就是 getter 和 setter 的用武之地。通过这种方式,您可以自己决定如何更改变量以及它们可以接收什么值,以及决定它们返回什么内容。

回到我们的家庭课程,让我们确保没有人可以将members 的值设置为小于 2 的任何值:

class family {
  var _members:Int = 2
  var members:Int {
    get {
      return _members
    }
    set (newVal) {
      if newVal >= 2 {
        _members = newVal
      } else {
        println('error: cannot have family with less than 2 members')
      }
    }
  }
}

现在我们可以像以前一样访问members 变量,方法是输入instanceOfFamily.members,并且由于setter 函数,我们还可以像以前一样设置它的值,例如:instanceOfFamily.members = 3。然而,改变的是我们不能再将此变量设置为小于 2 的任何值。

注意_members变量的引入,它是存储我们通过members setter函数设置的值的实际变量。原来的members现在变成了一个计算属性,这意味着它只作为一个接口来处理我们的实际变量。

【讨论】:

  • members ==> count, numberOfMembers; var members : Set<Person>??
  • set (newVal) { ... }, newVal 是隐含的,所以set { _members = newVal } 也是正确的。
  • 注意像_members这样的变量应该是私有的,否则命令instanceOfFamily._members=1会将instanceOfFamily.members设置为小于2的值
  • 看起来默认参数在 Swift 4 中被命名为 newValuedocs.swift.org/swift-book/LanguageGuide/Properties.html#ID260
【解决方案2】:

一个简单的问题后面应该有一个简短、简单和明确的答案。

  • 当我们获取属性的值时,它会触发其get{} 部分。

  • 当我们为属性设置值时,它会触发其set{} 部分。

PS。为属性设置值时,Swift 会自动创建一个名为“newValue”的常量 = 我们正在设置的值。在属性的set{} 部分可以访问常量“newValue”之后。

例子:

var A:Int = 0
var B:Int = 0

var C:Int {
get {return 1}
set {print("Recived new value", newValue, " and stored into 'B' ")
     B = newValue
     }
}

// When we are getting a value of C it fires get{} part of C property
A = C
A            // Now A = 1

// When we are setting a value to C it fires set{} part of C property
C = 2
B            // Now B = 2

【讨论】:

  • 是否必须为要从类外部访问的成员分配默认值。当我为其分配默认值时,我解决了这个问题 class UserBean:NSObject { var user_id: String? = nil } 像下面这样访问它 let user:UserBean = UserBean() user.user_id = "23232332"
【解决方案3】:

你应该看看Computed Properties

在您的代码示例中,perimeter 是一个不受类变量支持的属性。相反,它的值是使用 get 方法计算并通过 set 方法存储的 - 通常称为 gettersetter

当您像这样使用该属性时:

var cp = myClass.perimeter

您正在调用包含在get 代码块中的代码,并且当您像这样使用它时:

myClass.perimeter = 5.0

您正在调用包含在set 代码块中的代码,其中newValue 会自动填充赋值运算符右侧提供的值。

如果同时指定了 getter 和 setter,则计算属性可以是读/写的,如果只指定了 getter,则可以是只读的。

【讨论】:

    【解决方案4】:

    一个变量在一个类中这样声明和调用:

    class X {
        var x: Int = 3
    
    }
    
    var y = X()
    print("value of x is: ", y.x)
    
    //value of x is:  3
    
    

    现在您希望程序使 x 的默认值大于或等于 3。现在假设 x 小于 3:您的程序将失败。

    所以,您希望人们输入 3 或超过 3。Swift 对您来说很容易,理解这一点很重要 - 它是确定变量值的高级方法,因为他们会广泛使用它在 iOS 开发中。现在让我们看看这里将如何使用 getset

    class X {
        var _x: Int = 3
        var x: Int {
            get {
                return _x
            }
            set(newVal) {  // Set always take one argument
                if newVal >= 3 {
                    _x = newVal // Updating _x with the input value by the user
                    print("new value is: ", _x)
                }
                else {
                    print("error must be greater than 3")
                }
            }
        }
    }
    
    let y = X()
    y.x = 1
    print(y.x) // The error must be greater than 3
    y.x = 8 // // The new value is: 8
    
    

    如果您仍有疑问,请记住 getset 的使用是按照我们希望的方式更新任何变量。 getset 会让你更好地控制你的逻辑。它是一个强大的工具,因此不容易理解。

    【讨论】:

      猜你喜欢
      • 2015-09-06
      • 1970-01-01
      • 2013-02-17
      • 2016-04-27
      • 2015-06-05
      • 2014-10-28
      • 1970-01-01
      • 2011-02-06
      • 1970-01-01
      相关资源
      最近更新 更多