'get' และ 'set' ใน Swift คืออะไร?


106

ฉันกำลังเรียนรู้ 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...

ส่วนนี้ไม่ได้ระบุไว้ในหนังสือและฉันไม่สามารถรับสิ่งเหล่านั้นได้

ใครช่วยอธิบายหน่อยว่าget and setคืออะไร?


2
คุณอ่าน pg 21 เกี่ยวกับ getter / setter หรือไม่ นอกจากนี้ 30 pgs แรกหรือมากกว่านั้นเป็นทัวร์ชม Swift ไม่ใช่เอกสารฉบับเต็ม
vol7ron

หากคุณทำ C ++ แล้วคุณสามารถเชื่อมโยงสิ่งนี้ด้วยฟังก์ชัน getter และ setter member ของคลาส
CodingOnSteroid

คำตอบ:


41

ที่จริงแล้วอธิบายไว้ก่อนโค้ด:

นอกจากคุณสมบัติง่ายๆที่เก็บไว้แล้วคุณสมบัติยังมี 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;
}

109

การรับและการตั้งค่าของตัวแปรภายในคลาสหมายถึงการดึง ("getting") หรือการเปลี่ยนแปลง ("setting") เนื้อหาของมัน

พิจารณาตัวแปรของชั้นmembers familyโดยปกติแล้วตัวแปรนี้จะต้องเป็นจำนวนเต็มเนื่องจากครอบครัวไม่สามารถประกอบด้วยคนสองจุดได้

ดังนั้นคุณอาจจะดำเนินการต่อโดยกำหนดmembersตัวแปรดังนี้:

class family {
   var members:Int
}

อย่างไรก็ตามสิ่งนี้จะช่วยให้ผู้ที่ใช้คลาสนี้มีความเป็นไปได้ในการกำหนดจำนวนสมาชิกในครอบครัวเป็น 0 หรือ 1 และเนื่องจากไม่มีสิ่งที่เรียกว่าครอบครัว 1 หรือ 0 สิ่งนี้จึงค่อนข้างโชคร้าย

นี่คือที่มาของ getters และ setters วิธีนี้ทำให้คุณตัดสินใจได้ด้วยตัวเองว่าจะเปลี่ยนแปลงตัวแปรได้อย่างไรและรับค่าอะไรได้บ้างรวมทั้งตัดสินใจว่าจะส่งคืนเนื้อหาใด

กลับไปที่ชั้นเรียนครอบครัวของเราตรวจสอบให้แน่ใจว่าไม่มีใครกำหนด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 instanceOfFamily.members = 3อย่างไรก็ตามสิ่งที่เปลี่ยนแปลงไปคือความจริงที่ว่าเราไม่สามารถตั้งค่าตัวแปรนี้เป็นอะไรที่เล็กกว่า 2 ได้อีกต่อไป

สังเกตการแนะนำของ_membersตัวแปรซึ่งเป็นตัวแปรจริงในการจัดเก็บค่าที่เรากำหนดผ่านmembersฟังก์ชัน setter membersตอนนี้ต้นฉบับได้กลายเป็นคุณสมบัติที่คำนวณแล้วซึ่งหมายความว่ามันทำหน้าที่เป็นอินเทอร์เฟซเพื่อจัดการกับตัวแปรจริงของเราเท่านั้น


members==> count, numberOfMembers; var members : Set<Person>??
GoZoner

1
set (newVal) { ... }newVal เป็นนัยดังนั้นset { _members = newVal }ก็ถูกต้องเช่นกัน
AndreasHassing

4
สังเกตว่าตัวแปรเช่น _membersควรเป็นแบบส่วนตัวมิฉะนั้นคำสั่งinstanceOfFamily._members=1จะตั้งinstanceOfFamily.membersค่าต่ำกว่า 2
Daniel

ดูเหมือนว่าพารามิเตอร์เริ่มต้นถูกตั้งชื่อ newValueใน Swift 4 - docs.swift.org/swift-book/LanguageGuide/Properties.html#ID260
Nolan Amy

21

คำถามง่ายๆควรตามด้วยคำตอบสั้น ๆ ง่ายและชัดเจน

  • เมื่อเราได้รับมูลค่าของทรัพย์สินมันจะยิงget{}ส่วนของมัน

  • เมื่อเราตั้งค่าให้กับคุณสมบัติมันจะยิงset{}ส่วนของมัน

ปล. เมื่อตั้งค่าให้กับคุณสมบัติ 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} เข้าถึงได้เช่นเดียวกับผู้ใช้ต่อไปนี้: UserBean = UserBean () user.user_id = "23232332"
Amr Angry

2

คุณควรดูคุณสมบัติที่คำนวณ

ในตัวอย่างรหัสของคุณperimeterเป็นทรัพย์สินที่ไม่ได้รับการสนับสนุนจากตัวแปรระดับแทนค่าของมันจะคำนวณโดยใช้getวิธีการและเก็บไว้ผ่านทางsetวิธีการ - มักจะเรียกว่าทะเยอทะยานและหมา

เมื่อคุณใช้คุณสมบัติดังกล่าว:

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 ทำให้มันง่ายสำหรับคุณและสิ่งสำคัญคือต้องเข้าใจวิธีการหาค่าตัวแปรแบบ bit-advance นี้เพราะจะใช้อย่างกว้างขวางในการพัฒนา 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 and set คือการอัปเดตตัวแปรตามที่เราต้องการให้อัปเดต รับและตั้งค่าจะช่วยให้คุณควบคุมตรรกะของคุณได้ดีขึ้น เครื่องมือที่มีประสิทธิภาพจึงไม่สามารถเข้าใจได้ง่าย

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.