swift - Swift 4,泛型为什么我需要在这里转换为 T ?
问题描述
在 Swift 4 中运行此代码时,编译器会抛出以下错误:
"Cannot convert return expression of type 'Comment?' to return type '_?', when running this code in a playground:
import UIKit
class Comment {}
class Other {}
func itemForSelectedTabIndex<T>(index: Int, type: T.Type) -> T? {
return (type is Comment.Type) ? getComment() : getOther()
}
func getComment() -> Comment {
return Comment()
}
func getOther() -> Other {
return Other()
}
let thing = itemForSelectedTabIndex(index: 0, type: Other.self)
为了完成这项工作,我需要将返回值转换为泛型,如下所示:
return (type is Comment.Type) ? getComment() as! T : getOther() as! T
有人可以解释这背后的逻辑吗?
如果预期的返回值是“通用”,基本上我返回什么类型都没有关系,为什么编译器会抱怨它?这不应该在没有铸造的情况下工作吗?
解决方案
泛型不是一些在任何时候都可以具有任何价值的神奇通配符。
当你打电话时itemForSelectedTabIndex(index: 0, type: Comment.self)
,T
是推断出来的Comment
。同样,对于Other
.
当T
被推断为Comment
时,相同的值T
在使用它的所有地方都是一致的。因此,返回值必须是类型Comment
(或子类型)。
另一个是用你的表情(type is Comment.Type) ? getComment() : getOther()
。有 2 种情况,但均无效:
type
isComment.Type
:getComment()
返回 aComment
,一个与 的值兼容的类型,T
即Comment
。但是,条件运算符的两个操作数没有共同的超类型。那是无效的。type
is notComment.Type
:getOther()
返回一个Other
,它可能兼容也可能不兼容T
. 我们所知道T
的是它不是评论。这并不意味着它是必然的Other
。它可以是任何其他类型,例如Int
. 因此,此返回表达式失败。
您需要的是您希望返回的两种类型的通用超类型。最有可能的是,协议是正确的选择(而不是共享超类):
protocol TabItem {}
class Comment {}
class Other {}
func itemForSelectedTabIndex<T: TabItem>(index: Int, type: T.Type) -> TabItem {
return getCommentOrOtherOrSomethingElse()
}
推荐阅读
- angular - Angular OAuth2 检查 Guard 中的权限
- c# - 在返回导航中跳过 xamarin 表单中的页面
- python - 尝试通过网状包在 R 中使用 Python Gekko 时出错
- tfs - TFS2015 看不到项目文件,不能签入任何东西
- oracle - 我可以在 Oracle 数据库的 EXCEPTION 处理程序中获取 SQLSTATE 值吗?
- c++ - rapidjson 擦除数组并释放内存
- php - PhpStorm 调试问题
- openssl - OpenSSL 编译错误未定义参考
- android - Kotlin DSL Android 库的共享文件
- laravel - 使用 Woocommerce REST API“自动/woocommerce”上传图像时“抱歉,出于安全原因,不允许使用此文件类型”