Skip to content

关于 不透明类型和封装协议类型 中 不透明类型与封装协议类型之间的区别 的译注补充 #1412

Open
@Intro1997

Description

@Intro1997

Location

No response

Description

不透明类型与封装协议类型之间的区别这一节的这里 提到:

这种方法的另一个问题是形状变换无法嵌套

实际上在 Swift 5.7 之后,any Type 类型的对象,是可以传递给类型为 Type 的函数参数的,下面这个例子在 Swift 5.7 及之后的 Swift 版本运行时,不会出现错误:

protocol Shape {
  func draw() -> String
}

struct Square: Shape {
  var size: Int
  func draw() -> String {
    let line = String(repeating: "*", count: size)
    let result = [String](repeating: line, count: size)
    return result.joined(separator: "\n")
  }
}

struct Triangle: Shape {
  var size: Int
  func draw() -> String {
    var result: [String] = []
    for length in 1...size {
      result.append(String(repeating: "*", count: length))
    }
    return result.joined(separator: "\n")
  }
}

struct FlippedShape<T: Shape>: Shape {
  var shape: T
  func draw() -> String {
    if shape is Square {
      return shape.draw()
    }
    let lines = shape.draw().split(separator: "\n")
    return lines.reversed().joined(separator: "\n")
  }
}

func protoFlip<T: Shape>(_ shape: T) -> any Shape {
  if shape is Square {
    return shape
  }

  return FlippedShape(shape: shape)
}

let smallTriangle = Triangle(size: 3)
let protoFlippedTriangle = protoFlip(smallTriangle)
let unknownShape = protoFlip(protoFlippedTriangle)
print(unknownShape)

这个改动在 the third point of Future Directions 中有所提及:

Make existential types "self-conforming" by automatically opening them when passed as generic arguments to functions. Generic instantiations could have them opened as opaque types.

这应该就是为什么 Swift 在 5.7 版本后支持这种写法的原因了。我当时看到这里时,发现运行结果和原文描述不符,比较疑惑,新手看到这里可能也有这种感觉,因此希望这个可以作为译注添加到文档中,感谢!

Motivation

避免新手看到这一段时,因为代码执行结果和原文描述不符而感到困惑

Alternatives Considered

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions