Swift - 不透明型別和裝箱型別



有時開發人員希望隱藏有關型別的詳細資訊。因此,Swift 提供了兩種特殊的機制,稱為不透明型別和裝箱型別。使用這兩種機制,我們可以管理和抽象型別的底層細節。不透明型別用於在協議後面隱藏具體型別,而裝箱型別用於將值包裝在容器中。

不透明型別

不透明型別允許我們使用特定型別的值,而不顯示底層具體型別。或者我們可以說不透明型別用於隱藏其返回值型別。它根據協議支援來描述返回值,而不是顯示函式返回值的具體型別。它保留了型別標識,這意味著 Swift 編譯器可以訪問型別資訊,但模組的使用者無法訪問。

它透過隱藏函式或方法的返回型別並僅顯示符合某個協議或結構來增強程式碼的抽象性、封裝性和模組化。在 Swift 中,我們允許將不透明返回型別與泛型一起使用。此外,如果從多個位置返回具有不透明型別的函式,則該函式返回的所有值都必須具有相同的型別。

我們可以使用some關鍵字以及協議或型別來定義不透明型別。

語法

protocol ProtocolName {
   func methodName() -> String
}

func functionNAme() -> some ProtocolName {
   // Implementation that returns a type conforming to the given protocol}

示例

Swift 程式演示不透明型別。

// Function with return opaque type
func randomElement() -> some Equatable{ 
   Int.random(in: 0...14)
} 

let elementOne = randomElement()
let elementTwo = randomElement()

// Now comparing the first and second elements returned by the function 
print(elementOne == elementTwo)

輸出

它將產生以下輸出:

false

示例

Swift 程式演示不透明型別。

// Define a protocol for shapes
protocol Shape {
   func area() -> Double
}

// Implementing specific shapes  
struct Rectangle: Shape {
   let length: Double
   let breadth: Double 

   func area() -> Double {
      return length * breadth
   }
}

struct Triangle: Shape {
   let length: Double
   let height: Double
    
   func area() -> Double {
      return ((length * height) / 2)
   }
}
// Function to add areas of two different shapes using opaque type
func sumOfArea(rectShape: some Shape, triShape: some Shape) -> Double {
   return rectShape.area() + triShape.area()
}

let obj1 = Rectangle(length: 10.2, breadth: 11.0)
let obj2 = Triangle(length: 5.1, height: 6.0)
let totalArea = sumOfArea(rectShape: obj1, triShape: obj2)

print("Total Area is : \(totalArea)")

輸出

它將產生以下輸出:

Total Area is : 127.49999999999999

裝箱協議型別

裝箱協議型別用於將符合協議的型別包裝在容器內。它通常使用泛型型別或現有的型別,例如“Any”。它允許我們使用具有共同協議的不同型別的值,而無需顯示底層型別。

示例

Swift 程式演示不透明型別。

// Define a protocol
protocol Display {
   func details() -> String
}

// Implementing for specific types
struct Student: Display {
   var name: String
    
   func details() -> String {
      return "Student's Name: \(name)"
   }
}

struct Teacher: Display {
   var tname: String
    
   func details() -> String {
      return "Teacher's Name: \(tname)"
   }
}

// Wrapper type for boxed protocol
struct BoxedDisplay {
   let x: Display
    
   init(_ x: Display) {
      self.x = x
   }
}

// Function that accepts a boxed protocol type
func displayDetails(box: BoxedDisplay) {
   print(box.x.details())
}

// Instances
let obj1 = Student(name: "Monika")
let obj2 = Teacher(tname: "Mohit")

let box1 = BoxedDisplay(obj1)
let box2 = BoxedDisplay(obj2)

displayDetails(box: box1)
displayDetails(box: box2)

輸出

它將產生以下輸出:

Student's Name: Monika
Teacher's Name: Mohit

不透明型別和裝箱協議型別之間的區別

以下是**不透明型別**和**裝箱協議型別**的主要區別:

不透明型別 裝箱協議型別
它使用 some 關鍵字建立不透明型別。 它使用包裝型別建立裝箱協議型別。
它允許函式隱藏其返回型別。 它允許函式返回包裝在容器中的具體型別。
它提供型別擦除。 它可能具有或可能不具有型別擦除。
它隱藏了具體型別。 它包裝了特定型別。
廣告