在Swift中什么是“获取”和“设置”?


101

我正在学习Swift并且正在阅读 The Swift Programming Language从Apple,我没有Objective C背景(只有PHP,JS和其他语言,但是没有Obj C)

在24-25页上,我看到以下代码:

//...Class definition stuff...

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

//...Class continues...

这部分没有在书中指定,我无法理解它们的用途。

谁能解释我得到设定的是什么?


2
您是否阅读了第21页有关吸气剂/吸气剂的信息。另外,前30 pgs左右是Swift 之旅,而不是完整的文档。
vol7ron 2014年

如果您使用过C ++,则可以将此类与getter和setter成员函数
CodingOnSteroid

Answers:


38

其实是在代码之前进行了解释:

除了存储的简单属性外,属性还可以具有getter和setter。

class EquilateralTriangle: NamedShape {
    ...

当其他某个类想要获取该周边变量时,他们会这样做:

let someVar = myTriangle.perimeter

...这称为:

get{
    return 3.0 * self.sideLength
}

因此,本质上就像调用控制器执行此操作一样:

let someVar = 3.0 * myTriangle.sideLength

当您从另一个对象设置变量时,它看起来像这样:

myTriangle.perimeter = 100

哪个调用set{}块中的代码:

set {
    sideLength = newValue / 3.0
}

因此,就像设置变量的类是否做到了这一点:

myTriangle.sideLength = 100/3.0

实际上,这只是为了方便起见 -您可以从其他代码中调用此代码,而不必一直被3除或乘,因为这是在设置变量之前以及在获取变量之前完成的。

在Swift中,我们可以拥有在获取时可以计算的属性,并且在设置时可以执行某些操作。我们也可以在Objective-C中执行此操作:

// .h
@property (nonatomic) double perimeter;

//.m

- (double)perimeter
{
    return self.sideLength * 3.0;
}
- (void)setPerimeter:(double)perimeter
{
    self.perimeter = perimeter; // In Swift, this is done automatically.
    self.sideLength = perimeter / 3.0;
}

108

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

考虑members一个类的变量family。自然地,该变量必须是整数,因为一个家庭永远不能由两点东西组成。

因此,您可能会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变量的介绍,它是实际的变量,用于存储通过memberssetter函数设置的值。members现在,原始属性已成为计算属性,这意味着它仅充当处理实际变量的接口。


members==> countnumberOfMembers; var members : Set<Person>??
GoZoner 2014年

1
set (newVal) { ... }暗含newVal,因此set { _members = newVal }也是正确的。
AndreasHassing 2015年

4
请注意,like之类的变量_members应为私有变量,否则命令instanceOfFamily._members=1将设置instanceOfFamily.members为2以下的值
Daniel

看起来默认参数是newValue在Swift 4中命名的– docs.swift.org/swift-book/LanguageGuide/Properties.html#ID260
Nolan Amy

18

一个简单的问题之后应该是一个简短,简单而明确的答案。

  • 当我们获得财产的价值时,它就会解雇get{}

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

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

例:

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

1
是否必须为要从类外部访问的成员分配默认值?当我为其分配默认值时,就已经解决了此问题。类UserBean:NSObject {var user_id:String?= nil}的访问方式如下let user:UserBean = UserBean()user.user_id =“ 23232332”
Amr Angry

1

您应该查看计算属性

在您的代码示例中,perimeter是一个没有类变量支持的属性,而是使用get方法计算并通过set方法存储其值-通常称为gettersetter

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

var cp = myClass.perimeter

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

myClass.perimeter = 5.0

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

如果同时指定了getter和setter,则可读写属性;如果指定了getter,则只读。


0

变量在类中进行声明和调用

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开发中。现在,让我们看看如何在这里使用get和set。

class X {
    var _x: Int = 3
    var x: Int {
        get {
            return _x
        }
        set(newVal) {  //set always take 1 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) //error must be greater than 3
y.x = 8 // //new value is: 8

如果您仍然有疑问,请记住,get和set的使用是按照我们希望其更新的方式来更新任何变量。获取和设置将使您更好地控制规则。功能强大的工具因此不容易理解。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.