Tuple quot;upcastingquot; in Swift(元组“向上转型在斯威夫特)
问题描述
如果我有一个带有 (String, Bool)
签名的元组,我不能将它转换为 (String, Any)
.编译器说:
If I have a tuple with signature (String, Bool)
I cannot cast it to (String, Any)
. The compiler says:
错误:无法表达元组转换 '(String, Bool)' 到 '(String,任何)'
error: cannot express tuple conversion '(String, Bool)' to '(String, Any)'
但这应该可以工作,因为 Bool
可以使用 as
安全地转换为 Any
.如果你这样做,几乎会抛出相同的错误:
But this should work since Bool
can be casted safely to Any
with as
. Almost the same error gets thrown if you do something like that:
let any: Any = ("String", true)
any as! (String, Any) // error
any as! (String, Bool) // obviously succeeds
错误:
无法将 '(Swift.String, Swift.Bool)' 类型的值转换为'(协议<>, 协议<>)'
Could not cast value of type '(Swift.String, Swift.Bool)' to '(protocol<>, protocol<>)'
那么对于第二种情况,有什么解决方法吗?因为您甚至不能将 Any
转换为任何可以单独转换元素的元组 (Any, Any)
.
So is there any workaround especially for the second scenario? Because you cannot even cast Any
to any tuple (Any, Any)
where you could cast the elements separately.
推荐答案
元组不能转换,即使它们包含的类型可以.例如:
Tuples cannot be cast, even if the types they contain can. For example:
let nums = (1, 5, 9)
let doubleNums = nums as (Double, Double, Double) //fails
但是:
let nums : (Double, Double, Double) = (1, 5, 9) //succeeds
在您的情况下,解决方法是转换单个元素,而不是元组本身:
The workaround in your case is to cast the individual element, not the Tuple itself:
let tuple = ("String", true)
let anyTuple = (tuple.0, tuple.1 as Any)
// anyTuple is (String, Any)
这是原因之一 Swift 文档 注释:
This is one of the reasons the Swift documentation notes:
元组对于相关值的临时组很有用.它们不适合创建复杂的数据结构.如果您的数据结构可能会在临时范围之外持续存在,请将其建模为类或结构,而不是元组.
Tuples are useful for temporary groups of related values. They are not suited to the creation of complex data structures. If your data structure is likely to persist beyond a temporary scope, model it as a class or structure, rather than as a tuple.
我认为这是一个实现限制,因为元组是 复合类型 类函数.同样,您不能创建元组的扩展(例如 extension (String, Bool) { ... }
).
I think this is an implementation limitation because Tuples are compound types like functions. Similarly, you cannot create extensions of Tuples (e.g. extension (String, Bool) { … }
).
如果您实际使用的是返回 (String, Any)
的 API,请尝试将其更改为使用类或结构.但是如果你无力改进 API,你可以在第二个元素的类型上switch
:
If you're actually working with an API that returns (String, Any)
, try to change it to use a class or struct. But if you're powerless to improve the API, you can switch
on the second element's type:
let tuple : (String, Any) = ("string", true)
switch tuple.1 {
case let x as Bool:
print("It's a Bool")
let boolTuple = (tuple.0, tuple.1 as! Bool)
case let x as Double:
print("It's a Double")
let doubleTuple = (tuple.0, tuple.1 as! Double)
case let x as NSDateFormatter:
print("It's an NSDateFormatter")
let dateFormatterTuple = (tuple.0, tuple.1 as! NSDateFormatter)
default:
print("Unsupported type")
}
如果 API 返回 Any
并且元组不能保证是 (String, Any)
,那么你就倒霉了.
If the API returns Any
and the tuple isn't guaranteed to be (String, Any)
, you're out of luck.
这篇关于元组“向上转型"在斯威夫特的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:元组“向上转型"在斯威夫特
基础教程推荐
- android 应用程序已发布,但在 google play 中找不到 2022-01-01
- 如何在没有IB的情况下将2个按钮添加到右侧的UINavigationbar? 2022-01-01
- 如何在 iPhone 上显示来自 API 的 HTML 文本? 2022-01-01
- Kivy Buildozer 无法构建 apk,命令失败:./distribute.sh -m “kivy"d 2022-01-01
- Android:对话框关闭而不调用关闭 2022-01-01
- 在 gmail 中为 ios 应用程序检索朋友的朋友 2022-01-01
- 如何在 UIImageView 中异步加载图像? 2022-01-01
- 当从同一个组件调用时,两个 IBAction 触发的顺序是什么? 2022-01-01
- UIWebView 委托方法 shouldStartLoadWithRequest:在 WKWebView 中等效? 2022-01-01
- 如何让对象对 Cocos2D 中的触摸做出反应? 2022-01-01