【问题标题】:Cast to a Metatype Type in Swift?在 Swift 中转换为元类型?
【发布时间】:2015-01-12 07:34:22
【问题描述】:

你能在 Swift 中转换为元类型吗?看起来你真的应该能够(毕竟你可以从 Metatypes 实例化对象)。

以下不起作用:

class Super {}

class A : Super {}

let superA:Super = A()
let subType = superA.dynamicType
let afterCast = superA as subType 

//Compiler error: "use of undeclared type 'subType'"

有人知道正确的方法吗?

编辑:

正如 newacct 所指出的, .dynamicType 的结果显然要到运行时才知道,因此在编译时强制转换为 .dynamicType 的结果是没有意义的。

所以答案是:“你不能”(而且没有充分的理由去尝试)。

【问题讨论】:

  • 我猜你根本做不到。 let 创建的是实例,而不是类型。
  • 对不起,哪个let?你的意思是let subType = superA.dynamicType 创建一个实例?那么有没有办法访问类型本身(实际上是实例化一个 Metatype)?
  • 你能详细说明这会有什么用吗?
  • 在无法使用@objc 标签的各种情况之一中,这是向下转换为协议的复杂尝试的一部分。如果用我想知道的语言根本不可能,那么我可以尝试想一些不同的东西。关于 Metatype 类型的官方文档非常稀少,所以我想问一下。
  • 似乎是一种代码异味,可以通过强制转换为协议来解决 - 鼓励鸭子打字。没有更多信息很难确定

标签: swift


【解决方案1】:

首先,as 在右侧采用类型,而不是表达式。所以你有一个语法错误。

您似乎试图做的是将“强制转换”为在运行时计算的类型。这甚至意味着什么?我们先来看看什么是“演员表”。

通常,当我们有一个转换表达式x as T时,它有两个组件:

  • 在编译时:整个转换表达式x as T 具有编译时类型T?,它允许您对生成的表达式执行您可能无法直接在x 上执行的操作。换句话说,它允许您更改编译时类型。
  • 在运行时:检查x的运行时类型是否是T的子类型,如果是,则计算为包含该值的可选项,否则计算为nil

如果T 类型在编译时未知,那么显然你不能执行它的编译时部分。 (结果表达式的编译时类型显然不能依赖于编译时未知的东西。)

另一部分,运行时组件,可以用运行时计算的类型来完成吗?当然。例如,

import Foundation
let afterCast : Super? =
    (superA as AnyObject).isKindOfClass(subType) ? superA : nil

不清楚这是否是你想要的。

【讨论】:

  • 好的,我明白为什么您不能对来自 dynamicType 的结果执行编译时检查。所以你是对的,答案基本上是“不”。
  • 小细节:参考你的第一句话,元类型表达式不应该像类型一样吗?我对为什么这是语法错误感到有些困惑
  • @thekwiat:元类型类型的表达式或任何类型的表达式仍然是表达式。表达式在语法上与类型在不同的地方使用。
  • 好的,谢谢。为了将来参考,有没有办法从“元类型”中提取实际的“类型”?我想当您从元类型实例化对象时,这必须隐式发生......
  • @thekwiat:我不确定你是如何使用你的术语的,但我认为有一点混乱。在您的程序中,您有一个变量subType,它的值是一个类型。变量subType 的类型是元类型(type of a type)。但是subType 本身,我会说, 一种类型。因此,您是在“转换为类型”,而不是您的标题所暗示的“转换为元类型”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多