强制功能参数必须是可选的

时间:2018-09-27 17:52:06

标签: swift optional

我有一个自定义运算符?=,用于简单地将可选值分配给非可选值。

var a: String
let b: String?

a = b ?? a
// is simplified to
a ?= b

这很好用,但是当b不是可选的时,我不希望人们能够使用此运算符。它不会造成任何问题,但是看起来很糟糕,我不喜欢它。

我的函数签名当前为:

func ?=<T> (originalValue: inout T, optionalNewValue: T?)

当optionalNewValue实际上不是可选的时,我该如何引起编译器警告或错误?

2 个答案:

答案 0 :(得分:2)

正如其他人在评论中所说,?=运算符可能不是解决您问题的最佳解决方案。现在,如果您热衷于该运算符,或者为您的代码库增值,那么可以采用一种解决方法,使您可以拒绝运算符右侧的非可选值。

您可以将OptionalCompatible协议用于操作员的右侧:

protocol OptionalCompatible {
    associatedtype Wrapped
    var optionalValue: Wrapped? { get }
}

extension Optional: OptionalCompatible {
    var optionalValue: Wrapped? { return self }
}

func ?=<T, U> (originalValue: inout T, optionalNewValue: U) where U: OptionalCompatible, U.Wrapped == T {
    originalValue = optionalNewValue.optionalValue ?? originalValue
}

使用自定义协议会禁止将非可选选项自动升级为可选选项,从而仅允许使用可选选项。

但是有一个警告:理论上,一致性OptionalCompatible可以添加到任何类型。

答案 1 :(得分:1)

  

当optionalNewValue实际上不是可选的时,我该如何引起编译器警告或错误?

您不能。 Swift的一个内置事实是,总是可以在期望String url = "http://www.expedia.co.jp/" + URLEncoder.encode(Osaka-Hotels-Hotel-Consort.h5522663.Hotel-Information?", "UTF-8")的地方分配或传递T类型的nonOptional。