首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Swift中可选参数的泛型函数重载

Swift中可选参数的泛型函数重载
EN

Stack Overflow用户
提问于 2020-12-17 22:10:47
回答 2查看 197关注 0票数 1

我正在尝试编写一个使用模板/泛型类型分派的库,但我不知道Swift中重载解析是如何工作的。(是否有比Swift编程语言更多的技术参考?)

以下内容与我所希望的完全相同:

代码语言:javascript
运行
复制
func f(_ v: String) { print(v) }
func f(_ v: String?) { f(v!) }
func f(_ v: Int) { print(v) }
func f(_ v: Int?) { f(v!) }
f("foo")
f(Optional("bar"))
f(2)
f(Optional(3))

这个代码的工作方式也是一样的:

代码语言:javascript
运行
复制
func g<T>(_ v: T) { print(v) }
func g<T>(_ v: T?) { g(v!) }
g("foo")
g(Optional("bar"))
g(2)
g(Optional(3))

但是,当我编译它时:

代码语言:javascript
运行
复制
func h(_ v: String) { print(v) }
func h(_ v: Int) { print(v) }
func h<T>(_ v: T?) { h(v!) }
h("foo")
h(Optional("bar"))
h(2)
h(Optional(3))

我收到警告了

代码语言:javascript
运行
复制
all paths through this function will call itself
func h<T>(_ v: T?) { h(v!) }

当然,用一个可选的参数执行它会使堆栈失效。

我的第一个理论是,可能泛型不参与非泛型的过载解析,但以下是:

代码语言:javascript
运行
复制
func i<T: StringProtocol>(_ v: T) { print(v) }
func i<T>(_ v: T?) { i(v!) }
i("foo")
i(Optional("bar"))

给出同样的警告,第二次调用就会触发堆栈。

如果vOptional(String)类型的,我甚至不明白如何将v!传递给期望T?的泛型。

EN

回答 2

Stack Overflow用户

发布于 2020-12-17 22:25:57

这是因为在您的一般实现中不会发生任何类型推断。您可以通过执行一些可选的强制转换(以避免崩溃)并将其发送到正确的方法来解决这个问题,这种情况无论如何都会自动发生。所以,就像:

代码语言:javascript
运行
复制
func h<T>(_ v: T?) { 
  if let stringValue = v as? String {
    h(stringValue) 
  } else if let intValue = v as? Int {
    h(intValue) 
  }
}

也许有点违背了目的,但我可以告诉您,作为一个具有多年经验的Swift开发人员,如果您的其余代码是以Swift友好的方式编写的,这种类型的泛型处理不会/不应该在实际的应用程序中经常出现。我想这是基于观点的,但就是这样。

关于这一评论:

如果v是可选的(字符串),我甚至不明白v是怎么回事!可以传递给期望T?的泛型。

根据您的实现,您将声明v: T?,这意味着v必须是T类型或nil类型。因此,v!只是您(作为一个开发人员),保证v将是T类型,而不是nil,如果您错了,程序就会崩溃。

我假设您这样做只是为了学习目的,但这是我在示例代码中注意到的最大的事情--如果要立即使用,那么让方法接受可选参数是没有意义的!强行拆开。

票数 2
EN

Stack Overflow用户

发布于 2020-12-17 23:49:30

我希望更直接地回答泛型是如何工作的,但是Swift的协议和扩展提供了一种不同的方法来进行相同的分派。

代码语言:javascript
运行
复制
protocol H { func h() }
extension String: H { func h() { print(self) } }
extension Int: H { func h() { print(self) } }
extension Optional: H where Wrapped: H { func h() { self!.h() } }
"foo".h()
Optional("bar").h()
2.h()
Optional(3).h()
Optional(Optional(3)).h()

不幸的是,据我所知,这种分派机制不能应用于元组(或函数类型),因为它们不能被扩展。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65349037

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档