【问题标题】:Apple Swift: Type Casting GenericsApple Swift:类型转换泛型
【发布时间】:2014-06-22 20:36:23
【问题描述】:

我正在编写一些 Swift 代码,其中我有一个包含泛型类型的数组:

let _data: Array<T> = T[]()

稍后在我的代码中,我需要确定存储在数组中的类型。我尝试使用documentation 中描述的类型转换技术(尽管它没有用于泛型)。

switch self._data {
case let doubleData as Array<Double>:
  // Do something with doubleData
case let floatData as Array<Float>:
  // Do something with floatData
default:
  return nil // If the data type is unknown return nil
}

上面的switch语句在编译时出现如下错误:

  1. 在发射 IR SIL 函数时 @_TFC19Adder_Example___Mac6Matrix9transposeUS_7Element__fGS0_Q__FT_GSqGS0_Q___ 用于 /code.viperscience/Adder/src/Adder 的“转置” 库/Matrix.swift:45:3 :0: 错误:无法执行 命令:分段错误:11:0:错误:快速前端 命令因信号而失败(使用 -v 查看调用) 命令 /Applications/Xcode6-Beta2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift 退出代码 254 失败

有人知道我如何将我的通用数据转换为它的实际类型以便采取具体行动吗?

【问题讨论】:

  • 尝试使用as? 但我认为在你的情况下它是一个编译器错误......报告它!
  • 我尝试了可选的,但没有成功。我同意它可能是一个编译器错误。这不是我见过的与泛型有关的第一个......

标签: ios generics swift


【解决方案1】:

在 swift 中,as 运算符类似于 C++ 中的 dynamic_cast,可用于向下转换一个对象。

假设您有一个A 类型的对象a,并且只有当B 类型与A 类型相同或B 是@987654329 的子类时,您才能编写let a as B @。

在您的情况下,显然Array&lt;T&gt; 不能总是向下转换为Array&lt;Double&gt;Array&lt;Float&gt;,因此编译器会报告错误。

一个简单的解决方法是先转换为AnyObject,然后向下转换为Array&lt;Double&gt;Array&lt;Float&gt;

let anyData: AnyObject = self._data;
switch anyData {
case let doubleData as? Array<Double>: // use as? operator, instead of as,
                                       // to avoid runtime exception
  // Do something with doubleData
case let floatData as? Array<Float>:
  // Do something with floatData
default:
  return nil // If the data type is unknown return nil

【讨论】:

  • 感谢您的帮助,但我尝试了您的解决方案无济于事 - 尽管您的解释很有帮助。我意识到 Array 不能总是向下转换为 Array 或 Array 但这不是 switch 语句的用途吗?真的没关系......我认为这是编译器的错误。另外,使用 As?运算符只会产生另一个错误。 Apple 文档(请参阅我上面的链接)不使用 As?运算符,而只是 As 运算符。
【解决方案2】:

假设你有一个按钮数组:

let views: [NSView] = [NSButton(), NSButton(), NSButton()]

您可以使用这些演员表:

let viewsAreButtons = views is [NSButton]  // returns true
let buttonsForSure = views as! [NSButton]  // crashes if you are wrong
let buttonsMaybe = views as? [NSButton]    // optionally set

如果您尝试在下面的开关盒中使用 as,它将无法正常工作。编译器(Swift 1.2 Xcode 6.3b1)说:“不能使用 [NSButton] 类型的向下转换模式。”

switch views {
  case let buttons as [NSButton]:
    println("Buttons")
  default:
    println("something else")
}

称之为限制。用您的用例归档雷达。 Swift 团队真的很想听取反馈。如果你真的想让它工作,你可以定义自己的模式匹配运算符。在这种情况下,它会是这样的:

struct ButtonArray { }
let isButtonArray = ButtonArray()

func ~=(pattern: ButtonArray, value: [NSView]) -> Bool {
    return value is [NSButton]
}

然后这个工作:

switch views {
  case isButtonArray:
      println("Buttons")    // This gets printed.
  default:
     println("something else")
}

在游乐场尝试一下。希望对您有所帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-28
    • 1970-01-01
    相关资源
    最近更新 更多