加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

swift – 强制将单个参数传递给多可选参数函数

发布时间:2020-12-14 04:50:53 所属栏目:百科 来源:网络整理
导读:考虑以下功能: func myFunction(completion: (data: Data?,error: Error?) - ()) { } 我目前的要求是完成:只接受数据值或错误值,但不接受两者.一个人必须是零. 很容易将它们保持为可选,然后展开并稍后检查它们的值,但我认为如果编译器能够通知开发人员他们
考虑以下功能:

func myFunction(completion: (data: Data?,error: Error?) -> ()) { }

我目前的要求是完成:只接受数据值或错误值,但不接受两者.一个人必须是零.

很容易将它们保持为可选,然后展开并稍后检查它们的值,但我认为如果编译器能够通知开发人员他们不能同时设置它们会更好.

从另一个角度来看,知道其中一个将总是设置为someValue会更有用.

通过这种方式,您可以保证您将收到错误或数据,并且永远不必担心处理它们都是零的情况.

目前有办法做到这一点吗?

解决方法

你想要一些它无法做到的Swift.特别是,据我所知,Swift没有联合类型.如果你想要这样的东西,你可能想看看功能性或功能性的语言.

插曲:如果两种类型都是结构或类(即非协议),则可以使用此模式:

protocol DataOrError {}
extension Data: DataOrError {}
extension ErrorClass: DataOrError {}

假设没有协议的其他实现者,您现在有一些接近联合类型的东西.您也可以切换大小写类型:

switch doe {
    case let e as Error: print("Error (e)")
    case let d as Data: print("Data (d)")
    default: assert(false,"thou shalt not implement my dummy!")
}

无论如何,我们可以使用带有相关值的枚举来伪造它,这可以(有限制地)用作穷人的联合类型.

定义这样的枚举:

enum DataOrError {
    case Data(Data)
    case Error(Error)
}

现在您可以使用DataOrError,您可以(确切地)拥有Data或Error以及DataOrError之一吗?至多一个.

来电网站,您可以得到以下内容:

extension String: Error {} // low-effort errors,don't judge me!
func myFunction(completion: (DataOrError) -> ()) {
    completion(.Data(Data(bytes: [1,2,3,4,5])))
    completion(.Error("this won't work!"))
}

和被叫网站:

var myCompletion = { (doe: DataOrError) in
    switch doe {
        case .Data(let d): print("Data (d)")
        case .Error(let e): print("Error (e)")
    }
}

myFunction(completion: myCompletion)
// > Data 5 bytes
// > Error this won't work!

设计说明:您可能正在寻找另一个方向的概括,特别是如果您有许多不同类型的OR或Error.在这种情况下,即使您牺牲了良好的语法,显式包装器也可能是一个很好的解决方案.

struct TalkativeOptional<T> {
    private(set) var rawValue: T?
    private(set) var error: Error?

    init(value: T) {
        self.rawValue = value
    }

    init(error: Error) {
        self.error = error
    }
}

请注意两个属性中的一个属性是否为非零.还有两种组合;在这里,您可以通过选择初始化程序来控制所需的内容.

示例callee-site:

func convert(_ number: String) -> TalkativeOptional<Int> {
    if let int = Int(number) {
        return TalkativeOptional(value: int)
    } else {
        return TalkativeOptional(error: "'(number)' not a valid integer!")
    }
}

调用者站点示例:

var a = convert("dsa2e2")

if let val = a.rawValue {
    print("a + 1 = (val + 1)")
} else { // we know by design that error is set!
    print("ERROR: (a.error!)")
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读