Swift - Thuộc tính

Ngôn ngữ Swift 4 cung cấp các thuộc tính cho lớp, kiểu liệt kê hoặc cấu trúc để liên kết các giá trị. Thuộc tính có thể được phân loại thêm thành thuộc tính được lưu trữ và thuộc tính được tính toán.

Sự khác biệt giữa Thuộc tính được lưu trữ và Thuộc tính được tính

Tài sản lưu trữ Thuộc tính tính toán
Lưu trữ các giá trị hằng và biến dưới dạng phiên bản Tính toán một giá trị thay vì lưu trữ giá trị
Được cung cấp bởi các lớp và cấu trúc Được cung cấp bởi các lớp, kiểu liệt kê và cấu trúc

Cả hai thuộc tính được lưu trữ và tính toán đều được liên kết với loại phiên bản. Khi các thuộc tính được liên kết với các giá trị kiểu của nó thì nó được định nghĩa là 'Thuộc tính kiểu'. Các thuộc tính được lưu trữ và tính toán thường được liên kết với các phiên bản của một loại cụ thể. Tuy nhiên, các thuộc tính cũng có thể được liên kết với chính kiểu đó. Thuộc tính như vậy được gọi là thuộc tính kiểu. Người quan sát tài sản cũng được sử dụng

  • Để quan sát giá trị của các thuộc tính được lưu trữ
  • Để quan sát thuộc tính của lớp con kế thừa có nguồn gốc từ lớp cha

Thuộc tính được lưu trữ

Swift 4 giới thiệu khái niệm Thuộc tính lưu trữ để lưu trữ các thể hiện của hằng và biến. Các thuộc tính được lưu trữ của hằng số được xác định bởi từ khóa 'let' và các thuộc tính được lưu trữ của các biến được xác định bởi từ khóa 'var'.

  • Trong định nghĩa Thuộc tính được lưu trữ cung cấp 'giá trị mặc định'
  • Trong quá trình khởi tạo, người dùng có thể khởi tạo và sửa đổi các giá trị ban đầu
struct Number {
   var digits: Int
   let pi = 3.1415
}

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

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

Khi chúng tôi chạy chương trình trên bằng sân chơi, chúng tôi nhận được kết quả sau:

67
3.1415

Hãy xem xét dòng sau trong đoạn mã trên:

let pi = 3.1415

Ở đây, biến pi được khởi tạo như một giá trị thuộc tính được lưu trữ với ví dụ pi = 3,1415. Vì vậy, bất cứ khi nào cá thể được tham chiếu, nó sẽ giữ giá trị 3,1415 một mình.

Một phương pháp khác để có thuộc tính được lưu trữ là có các cấu trúc không đổi. Vì vậy, toàn bộ thể hiện của cấu trúc sẽ được coi là 'Thuộc tính được lưu trữ của hằng số'.

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

Khi chúng tôi chạy chương trình trên bằng sân chơi, chúng tôi nhận được kết quả sau:

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

Thay vì khởi động lại 'số' thành 8.7, nó sẽ trả về thông báo lỗi cho biết 'số' được khai báo là hằng số.

Tài sản được lưu trữ lười biếng

Swift 4 cung cấp một thuộc tính linh hoạt được gọi là 'Lazy Stored Property', nơi nó sẽ không tính toán các giá trị ban đầu khi biến được khởi tạo lần đầu tiên. "lazy" sửa đổi được sử dụng trước khi khai báo biến để có nó như một thuộc tính lưu trữ lười biếng.

Thuộc tính Lazy được sử dụng -

  • Để trì hoãn việc tạo đối tượng.
  • Khi thuộc tính phụ thuộc vào các phần khác của một lớp, điều đó chưa được biết đến
class sample {
   lazy var no = number()    // `var` declaration is required.
}

class number {
   var name = "Swift 4"
}

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

Khi chúng tôi chạy chương trình trên bằng sân chơi, chúng tôi nhận được kết quả sau:

Swift 4

Biến thể hiện

Trong Objective C, thuộc tính Stored cũng có các biến thể hiện cho mục đích sao lưu để lưu trữ các giá trị được khai báo trong thuộc tính được lưu trữ.

Swift 4 tích hợp cả hai khái niệm này vào một khai báo 'thuộc tính được lưu trữ' duy nhất. Thay vì có một biến phiên bản tương ứng và giá trị sao lưu 'thuộc tính được lưu trữ' chứa tất cả thông tin tích hợp được xác định ở một vị trí duy nhất về thuộc tính biến theo tên biến, kiểu dữ liệu và chức năng quản lý bộ nhớ.

Thuộc tính tính toán

Thay vì lưu trữ các giá trị, các thuộc tính đã tính toán cung cấp một getter và một setter tùy chọn để truy xuất và đặt các thuộc tính và giá trị khác một cách gián tiếp.

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)

Khi chúng tôi chạy chương trình trên bằng sân chơi, chúng tôi nhận được kết quả sau:

(150.0, 75.0)
-150.0
-65.0

Khi một thuộc tính được tính toán để lại giá trị mới là không xác định, giá trị mặc định sẽ được đặt cho biến cụ thể đó.

Thuộc tính được tính toán dưới dạng thuộc tính chỉ đọc

Thuộc tính chỉ đọc trong thuộc tính được tính toán được định nghĩa là thuộc tính có getter nhưng không có setter. Nó luôn được sử dụng để trả về một giá trị. Các biến được tiếp tục truy cập thông qua dấu '.' Cú pháp nhưng không thể được đặt thành giá trị khác.

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"]!)

Khi chúng tôi chạy chương trình trên bằng sân chơi, chúng tôi nhận được kết quả sau:

Swift 4 Properties
3.09

Thuộc tính được tính toán với tư cách là người quan sát thuộc tính

Trong Swift 4 để quan sát và phản hồi các giá trị thuộc tính, Trình quan sát tài sản được sử dụng. Mỗi và mọi lúc khi các giá trị thuộc tính được thiết lập, các trình quan sát thuộc tính được gọi. Ngoại trừ các thuộc tính được lưu trữ lười biếng, chúng ta có thể thêm các trình quan sát thuộc tính vào thuộc tính 'kế thừa' bằng phương pháp 'ghi đè'.

Người quan sát thuộc tính có thể được xác định bởi

  • Trước khi lưu trữ giá trị - willset

  • Sau khi lưu trữ giá trị mới - didset

  • Khi một thuộc tính được đặt trong bộ khởi tạo sẽ thiết lập và không thể gọi các quan sát viên 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

Khi chúng tôi chạy chương trình trên bằng sân chơi, chúng tôi nhận được kết quả sau:

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

Biến cục bộ và toàn cục

Biến cục bộ và toàn cục được khai báo để tính toán và quan sát các thuộc tính.

Biến cục bộ Biến toàn cục
Các biến được xác định trong một hàm, phương thức hoặc ngữ cảnh đóng. Các biến được xác định bên ngoài ngữ cảnh hàm, phương thức, bao đóng hoặc kiểu.
Dùng để lưu trữ và truy xuất các giá trị. Dùng để lưu trữ và truy xuất các giá trị.
Thuộc tính được lưu trữ được sử dụng để lấy và đặt các giá trị. Thuộc tính được lưu trữ được sử dụng để lấy và đặt các giá trị.
Các thuộc tính được tính toán cũng được sử dụng. Các thuộc tính được tính toán cũng được sử dụng.

Loại Thuộc tính

Thuộc tính được định nghĩa trong phần Định nghĩa kiểu với dấu ngoặc nhọn {} và phạm vi của các biến cũng đã được xác định trước đó. Để xác định thuộc tính kiểu cho các kiểu giá trị, từ khóa 'static' được sử dụng và từ khóa 'class' được sử dụng cho các loại lớp.

Cú pháp

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
   }
}

Truy vấn và thiết lập thuộc tính

Cũng giống như thuộc tính instance Thuộc tính loại được truy vấn và đặt bằng '.' Cú pháp chỉ trên loại thay vì trỏ đến cá thể.

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)

Khi chúng tôi chạy chương trình trên bằng sân chơi, chúng tôi nhận được kết quả sau:

97
87