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 关键字创建不透明类型。 它使用包装类型创建装箱协议类型。
它允许函数隐藏其返回类型。 它允许函数返回包装在容器中的具体类型。
它提供类型擦除。 它可能具有或可能不具有类型擦除。
它隐藏了具体类型。 它包装了特定类型。
广告