swift - 为什么公共类型会抛出私有类型的错误?
问题描述
为什么这段代码会编译?
// ===============
// MyStruct.swift
// ===============
private enum MyError: Error {
case unexpectedError
}
public struct MyStruct {
static func throwError() throws {
throw MyError.unexpectedError
}
}
// ===============
// main.swift
// ===============
do {
try MyStruct.throwError()
}
catch {
print(error) // "unexpectedError"
}
关于访问控制的文档非常清楚,我们不能在公共类型成员中返回私有类型:
函数的访问级别不能高于其参数类型和返回类型
前面的语句对我来说似乎很明显,下面的示例显示了它如何无法编译(我们现在返回它而不是抛出它):
private enum MyError: Error {
case unexpectedError
}
public struct MyStruct {
// Note: we are now returning `MyError` instead of throwing
static func returnError() -> MyError { // Error: Method must be declared fileprivate because its result uses a private type
return MyError.unexpectedError
}
}
对我来说似乎并不明显并且文档中没有提到的是,为什么我们可以将这个私有类型 ( )扔到MyError
公共类型 ( MyStruct
) 的方法中。
解决方案
您可以轻松地返回私有类型的东西
private enum MyError : Error {
case unexpectedError
}
public struct MyStruct {
static func myError() -> Error {
return MyError.unexpectedError
}
}
...通过将其隐藏为非私有类型的值。这只是子类型。或:unexpectedError
属于 类型,MyError
但它也是Error
. 你不能暴露type MyError
,但是你可以对它的值做任何你想做的事情,只要你不告诉任何人比“这些是Error
s”更具体的事情。
同样,您可以轻松地抛出私有类型的东西
public struct MyStruct {
static func throwError() throws {
throw MyError.unexpectedError
}
}
因为throw
想要一个Error
,你给它一个MyError
,和MyError : Error
。注释本身并throws
没有说明throwError
throwing MyError
s; 它只是说它通常可能会抛出Error
s。
推荐阅读
- spring-boot - 使用spring cloud feign的spring集成时出现BeanCurrentlyInCreationException
- c# - 生存射击团结敌人不会受到伤害
- android - Dagger 2 Injector 并使用 IntKey 绑定 IntoMap
- php - 1X5矩阵树结构PHP数组
- node.js - 在NodeJS中检测一个数字是否可以被100整除
- python - 需要登录时使用 python 从 cloud.google.com 下载公共文件
- windows - 如何缩短 Git Bash 提示 (Windows)
- sql - 奇怪的 SQL 远程查询
- python - Python 子进程 - 在创建的新命令提示符中运行第二个命令
- swift - Firestore 收集侦听器大量读取