Swift - คุณสมบัติ

ภาษา Swift 4 มีคุณสมบัติสำหรับคลาสการแจงนับหรือโครงสร้างเพื่อเชื่อมโยงค่า คุณสมบัติสามารถแบ่งออกเป็นคุณสมบัติที่เก็บไว้และคุณสมบัติที่คำนวณได้

ความแตกต่างระหว่างคุณสมบัติที่จัดเก็บและคุณสมบัติที่คำนวณ

ทรัพย์สินที่จัดเก็บ ทรัพย์สินที่คำนวณ
เก็บค่าคงที่และค่าตัวแปรเป็นอินสแตนซ์ คำนวณค่าแทนการเก็บค่า
จัดทำโดยคลาสและโครงสร้าง จัดทำโดยชั้นเรียนการแจงนับและโครงสร้าง

ทั้งคุณสมบัติที่จัดเก็บและคำนวณจะเชื่อมโยงกับประเภทอินสแตนซ์ เมื่อคุณสมบัติเชื่อมโยงกับค่าประเภทแล้วจะถูกกำหนดเป็น 'Type Properties' คุณสมบัติที่จัดเก็บและคำนวณมักจะเกี่ยวข้องกับอินสแตนซ์ของประเภทหนึ่ง ๆ อย่างไรก็ตามคุณสมบัติสามารถเชื่อมโยงกับชนิดได้ คุณสมบัติดังกล่าวเรียกว่าคุณสมบัติประเภท ยังใช้ผู้สังเกตการณ์ทรัพย์สิน

  • เพื่อสังเกตค่าของคุณสมบัติที่เก็บไว้
  • เพื่อสังเกตคุณสมบัติของคลาสย่อยที่สืบทอดมาจากซูเปอร์คลาส

คุณสมบัติที่เก็บไว้

Swift 4 แนะนำแนวคิด Stored Property เพื่อจัดเก็บอินสแตนซ์ของค่าคงที่และตัวแปร คุณสมบัติที่เก็บไว้ของค่าคงที่กำหนดโดยคีย์เวิร์ด 'let' และคุณสมบัติ Stored ของตัวแปรถูกกำหนดโดยคีย์เวิร์ด 'var'

  • ระหว่างนิยามคุณสมบัติที่จัดเก็บไว้ให้ 'ค่าเริ่มต้น'
  • ในระหว่างการเตรียมใช้งานผู้ใช้สามารถเริ่มต้นและแก้ไขค่าเริ่มต้นได้
struct Number {
   var digits: Int
   let pi = 3.1415
}

var n = Number(digits: 12345)
n.digits = 67

print("\(n.digits)")
print("\(n.pi)")

เมื่อเรารันโปรแกรมข้างต้นโดยใช้สนามเด็กเล่นเราจะได้ผลลัพธ์ดังนี้ -

67
3.1415

พิจารณาบรรทัดต่อไปนี้ในโค้ดด้านบน -

let pi = 3.1415

ที่นี่ตัวแปร pi จะเริ่มต้นเป็นค่าคุณสมบัติที่เก็บไว้โดยมีอินสแตนซ์ pi = 3.1415 ดังนั้นเมื่อใดก็ตามที่อ้างอิงอินสแตนซ์มันจะเก็บค่า 3.1415 ไว้เพียงอย่างเดียว

อีกวิธีหนึ่งในการจัดเก็บคุณสมบัติคือการมีโครงสร้างคงที่ ดังนั้นโครงสร้างทั้งหมดจะถือว่าเป็น 'คุณสมบัติที่เก็บไว้ของค่าคงที่'

struct Number {
   var digits: Int
   let numbers = 3.1415
}

var n = Number(digits: 12345)
n.digits = 67

print("\(n.digits)")
print("\(n.numbers)")
n.numbers = 8.7

เมื่อเรารันโปรแกรมข้างต้นโดยใช้สนามเด็กเล่นเราจะได้ผลลัพธ์ดังนี้ -

error: cannot assign to 'numbers' in 'n'
n.numbers = 8.7

แทนที่จะเริ่มต้น 'number' เป็น 8.7 จะส่งกลับข้อความแสดงข้อผิดพลาดที่ระบุว่า 'number' ถูกประกาศเป็นค่าคงที่

ขี้เกียจเก็บทรัพย์สิน

Swift 4 มีคุณสมบัติที่ยืดหยุ่นที่เรียกว่า 'Lazy Stored Property' ซึ่งจะไม่คำนวณค่าเริ่มต้นเมื่อตัวแปรถูกเตรียมใช้งานเป็นครั้งแรก ตัวปรับแต่ง 'lazy' ถูกใช้ก่อนการประกาศตัวแปรเพื่อให้เป็นคุณสมบัติที่เก็บไว้อย่างขี้เกียจ

ใช้ Lazy Properties -

  • เพื่อชะลอการสร้างวัตถุ
  • เมื่อคุณสมบัติขึ้นอยู่กับส่วนอื่น ๆ ของคลาสที่ยังไม่เป็นที่รู้จัก
class sample {
   lazy var no = number()    // `var` declaration is required.
}

class number {
   var name = "Swift 4"
}

var firstsample = sample()
print(firstsample.no.name)

เมื่อเรารันโปรแกรมข้างต้นโดยใช้สนามเด็กเล่นเราจะได้ผลลัพธ์ดังนี้ -

Swift 4

ตัวแปรอินสแตนซ์

ใน Objective C คุณสมบัติที่จัดเก็บยังมีตัวแปรอินสแตนซ์สำหรับวัตถุประสงค์ในการสำรองข้อมูลเพื่อเก็บค่าที่ประกาศไว้ในคุณสมบัติที่เก็บไว้

Swift 4 รวมแนวคิดทั้งสองนี้ไว้ในการประกาศ 'คุณสมบัติที่เก็บไว้' รายการเดียว แทนที่จะมีตัวแปรอินสแตนซ์ที่สอดคล้องกันและสำรองค่า 'คุณสมบัติที่เก็บไว้' จะมีข้อมูลรวมทั้งหมดที่กำหนดไว้ในตำแหน่งเดียวเกี่ยวกับคุณสมบัติของตัวแปรตามชื่อตัวแปรชนิดข้อมูลและฟังก์ชันการจัดการหน่วยความจำ

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

แทนที่จะเก็บค่าคุณสมบัติที่คำนวณแล้วให้ getter และ setter ทางเลือกเพื่อดึงและตั้งค่าคุณสมบัติและค่าอื่น ๆ โดยอ้อม

class sample {
   var no1 = 0.0, no2 = 0.0
   var length = 300.0, breadth = 150.0

   var middle: (Double, Double) {
      get {
         return (length / 2, breadth / 2)
      }
      
      set(axis){
         no1 = axis.0 - (length / 2)
         no2 = axis.1 - (breadth / 2)
      }
   }
}

var result = sample()
print(result.middle)
result.middle = (0.0, 10.0)

print(result.no1)
print(result.no2)

เมื่อเรารันโปรแกรมข้างต้นโดยใช้สนามเด็กเล่นเราจะได้ผลลัพธ์ดังนี้ -

(150.0, 75.0)
-150.0
-65.0

เมื่อคุณสมบัติที่คำนวณแล้วปล่อยให้ค่าใหม่เป็นไม่ได้กำหนดค่าเริ่มต้นจะถูกตั้งค่าสำหรับตัวแปรเฉพาะนั้น

คุณสมบัติที่คำนวณเป็นคุณสมบัติอ่านอย่างเดียว

คุณสมบัติอ่านอย่างเดียวในคุณสมบัติที่คำนวณได้ถูกกำหนดให้เป็นคุณสมบัติที่มี getter แต่ไม่มีตัวตั้งค่า จะใช้เพื่อส่งคืนค่าเสมอ ตัวแปรสามารถเข้าถึงได้เพิ่มเติมผ่านทาง "." ไวยากรณ์ แต่ไม่สามารถตั้งค่าเป็นค่าอื่นได้

class film {
   var head = ""
   var duration = 0.0
   var metaInfo: [String:String] {
      return [
         "head": self.head,
         "duration":"\(self.duration)"
      ]
   }
}

var movie = film()
movie.head = "Swift 4 Properties"
movie.duration = 3.09

print(movie.metaInfo["head"]!)
print(movie.metaInfo["duration"]!)

เมื่อเรารันโปรแกรมข้างต้นโดยใช้สนามเด็กเล่นเราจะได้ผลลัพธ์ดังนี้ -

Swift 4 Properties
3.09

คุณสมบัติที่คำนวณเป็นผู้สังเกตการณ์ทรัพย์สิน

ใน Swift 4 เพื่อสังเกตและตอบสนองต่อค่าคุณสมบัติ Property Observers ถูกใช้ ทุกครั้งเมื่อมีการตั้งค่าคุณสมบัติผู้สังเกตการณ์คุณสมบัติจะถูกเรียก ยกเว้นคุณสมบัติที่เก็บไว้แบบขี้เกียจเราสามารถเพิ่มผู้สังเกตการณ์คุณสมบัติให้กับคุณสมบัติ 'สืบทอด' โดยวิธีการ 'แทนที่'

ผู้สังเกตการณ์คุณสมบัติสามารถกำหนดโดยอย่างใดอย่างหนึ่ง

  • ก่อนจัดเก็บค่า - จะตั้งค่า

  • หลังจากจัดเก็บค่าใหม่ - didset

  • เมื่อคุณสมบัติถูกตั้งค่าใน initializer willset และไม่สามารถเรียกผู้สังเกตการณ์ didset ได้

class Samplepgm {
   var counter: Int = 0 {
      willSet(newTotal){
         print("Total Counter is: \(newTotal)")
      }
      
      didSet {
         if counter > oldValue {
            print("Newly Added Counter \(counter - oldValue)")
         }
      }
   }
}

let NewCounter = Samplepgm()
NewCounter.counter = 100
NewCounter.counter = 800

เมื่อเรารันโปรแกรมข้างต้นโดยใช้สนามเด็กเล่นเราจะได้ผลลัพธ์ดังนี้ -

Total Counter is: 100
Newly Added Counter 100
Total Counter is: 800
Newly Added Counter 700

ตัวแปรท้องถิ่นและทั่วโลก

มีการประกาศตัวแปรท้องถิ่นและทั่วโลกสำหรับการคำนวณและการสังเกตคุณสมบัติ

ตัวแปรท้องถิ่น ตัวแปรส่วนกลาง
ตัวแปรที่กำหนดภายในฟังก์ชันวิธีการหรือบริบทการปิด ตัวแปรที่กำหนดไว้ภายนอกฟังก์ชันวิธีการปิดหรือบริบทประเภท
ใช้ในการจัดเก็บและดึงค่า ใช้ในการจัดเก็บและดึงค่า
คุณสมบัติที่เก็บไว้ใช้เพื่อรับและตั้งค่า คุณสมบัติที่เก็บไว้ใช้เพื่อรับและตั้งค่า
นอกจากนี้ยังใช้คุณสมบัติที่คำนวณได้ นอกจากนี้ยังใช้คุณสมบัติที่คำนวณได้

พิมพ์ Properties

Properties are defined in the Type definition section with curly braces {} and scope of the variables are also defined previously. For defining type properties for value types 'static' keyword is used and for class types 'class' keyword is used.

Syntax

struct Structname {
   static var storedTypeProperty = " "
   static var computedTypeProperty: Int {
      // return an Int value here
   }
}

enum Enumname {
   static var storedTypeProperty = " "
   static var computedTypeProperty: Int {
      // return an Int value here
   }
}

class Classname {
   class var computedTypeProperty: Int {
      // return an Int value here
   }
}

Querying and Setting Properties

Just like instance properties Type properties are queried and set with '.' Syntax just on the type alone instead of pointing to the instance.

struct StudMarks {
   static let markCount = 97
   static var totalCount = 0
   
   var InternalMarks: Int = 0 {
      didSet {
         if InternalMarks > StudMarks.markCount {
            InternalMarks = StudMarks.markCount
         }
         if InternalMarks > StudMarks.totalCount {
            StudMarks.totalCount = InternalMarks
         }
      }
   }
}

var stud1Mark1 = StudMarks()
var stud1Mark2 = StudMarks()

stud1Mark1.InternalMarks = 98
print(stud1Mark1.InternalMarks)

stud1Mark2.InternalMarks = 87
print(stud1Mark2.InternalMarks)

When we run the above program using playground, we get the following result −

97
87