什么是'获得'和'设置'?

Mr.*_*Web 91 accessor swift

我正在学习Swift,我正在读The Swift Programming LanguageApple,我没有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...
Run Code Online (Sandbox Code Playgroud)

这部分未在书中指定,我无法得到它们的用途.

谁能解释一下这个获取设置是什么?

小智 105

在类中获取和设置变量是指检索("获取")或更改("设置")其内容.

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

所以你可能会继续这样定义members变量:

class family {
   var members:Int
}
Run Code Online (Sandbox Code Playgroud)

然而,这将使使用该类的人有可能将家庭成员的数量设置为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')
     }
   }
  }
}
Run Code Online (Sandbox Code Playgroud)

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

请注意_members变量的引入,该变量是存储我们通过memberssetter函数设置的值的实际变量.原始members现在已成为计算属性,这意味着它只作为处理我们实际变量的接口.

  • 请注意,像`_members`这样的变量应该是私有的,否则命令`instanceOfFamily._members = 1`会将`instanceOfFamily.members`设置为低于2的值 (4认同)

Und*_*ndo 33

这实际上是在代码之前解释的:

除了存储的简单属性之外,属性还可以包含getter和setter.

class EquilateralTriangle: NamedShape {
    ...
Run Code Online (Sandbox Code Playgroud)

当其他一些类想要获取该外围变量时,他们会这样做:

let someVar = myTriangle.perimeter
Run Code Online (Sandbox Code Playgroud)

......这称之为:

get{
    return 3.0 * self.sideLength
}
Run Code Online (Sandbox Code Playgroud)

因此,它基本上就像调用控制器这样做:

let someVar = 3.0 * myTriangle.sideLength
Run Code Online (Sandbox Code Playgroud)

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

myTriangle.perimeter = 100
Run Code Online (Sandbox Code Playgroud)

其中调用set{}块中的代码:

set {
    sideLength = newValue / 3.0
}
Run Code Online (Sandbox Code Playgroud)

因此,如果设置变量的类已完成此操作:

myTriangle.sideLength = 100/3.0
Run Code Online (Sandbox Code Playgroud)

这只是为了方便 - 您可以从其他代码中调用它,而不必一直除以或乘以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;
}
Run Code Online (Sandbox Code Playgroud)


小智 16

一个简单的问题应该是一个简短而简单明了的答案.

  • 当我们获得该物业的价值时,它会激活它的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
Run Code Online (Sandbox Code Playgroud)


Ant*_*nio 7

您应该查看计算属性

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

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

var cp = myClass.perimeter
Run Code Online (Sandbox Code Playgroud)

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

myClass.perimeter = 5.0
Run Code Online (Sandbox Code Playgroud)

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

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


sar*_*ran 5

变量在类中声明和调用如下:

class X {
    var x: Int = 3

}

var y = X()
print("value of x is: ", y.x)

//value of x is:  3

Run Code Online (Sandbox Code Playgroud)

现在您希望程序使 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

Run Code Online (Sandbox Code Playgroud)

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