【问题标题】:Swift anomalies between Any and AnyObjectAny 和 AnyObject 之间的 Swift 异常
【发布时间】:2014-07-24 19:15:50
【问题描述】:

我一直在玩 Swift。我正在尝试创建一个包含已知不同类型的 Swift 变量的数组。

我可以使用 Any 数组或 AnyObject 数组来完成大部分工作——但也不能完成完整的工作。我发现了一些异常——但我不知道它们是错误还是功能。

这是创建和测试数组的代码:

import UIKit
import Foundation

var aA: Array = [Any]()
aA.append("a String")          // Defaults to String
aA.append(123)                 // Defaults to Int
aA.append(-456.00)             // Defaults to Double
aA.append(0.33 as Float)       // Must cast as Float
aA.append(false)               // Defaults to Bool
aA.append("C" as Character)    // Must cast as Character

println("\naA: \(aA)\n")
(aA[0] is String)    ? println("aA[0] is String:    \(aA[0])") : println("aA[0] is Not String: \(aA[0])")
(aA[1] is Int)       ? println("aA[1] is Int:       \(aA[1])") : println("aA[1] is Not Int:    \(aA[1])")
(aA[2] is Double)    ? println("aA[2] is Double:    \(aA[2])") : println("aA[2] is Not Double: \(aA[2])")
(aA[3] is Float)     ? println("aA[3] is Float:     \(aA[3])") : println("aA[3] is Not Float:  \(aA[5])")
(aA[4] is Bool)      ? println("aA[4] is Bool:      \(aA[4])") : println("aA[4] is Not Bool:   \(aA[4])")
(aA[5] is String)    ? println("aA[5] is String:    \(aA[5])") : println("aA[5] is Not String: \(aA[5])")
(aA[5] is Character) ? println("aA[5] is Character: \(aA[5])") : println("aA[5] is Not Character: \(aA[5])")

var aO = [AnyObject]()
aO.append("a String")          // Defaults to String
aO.append(123)                 // Defaults to Int
aO.append(-456.00)             // Defaults to Double
aO.append(0.33)                // Defaults as Float
aO.append(false)               // Defaults to Bool
aO.append("C")                 // Defaults to String -- Cannot cast as Character

println("\naO: \(aO)\n")
(aO[0] is String) ? println("aO[0] is String: \(aO[0])") : println("aO[0] is Not String: \(aO[0])")
(aO[1] is Int)    ? println("aO[1] is Int:    \(aO[1])") : println("aO[1] is Not Int:    \(aO[1])")
(aO[2] is Double) ? println("aO[2] is Double: \(aO[2])") : println("aO[2] is Not Double: \(aO[2])")
(aO[3] is Float)  ? println("aO[3] is Float:  \(aO[3])") : println("aO[3] is Not Float:  \(aO[5])")
(aO[4] is Bool)   ? println("aO[4] is Bool:   \(aO[4])") : println("aO[4] is Not Bool:   \(aO[4])")
(aO[5] is String) ? println("aO[5] is String: \(aO[5])") : println("aO[5] is Not String: \(aO[5])")


/*

Anomalies between Any and AnyObject

aA[2] -456.00 Double returns -456.0 ................... aO[2] -456.00 Double returns -456
aA[3] 0.33 Must cast as Float ......................... aO[3] 0.33 defaults to Float
aA[3] 0.33 Float returns 0.330000013113022 ............ aO[3] 0.33 Float returns 0.33
aA[4] false Bool returns false ........................ aO[4] false Bool returns 0
aA[5] "C" Defaults to String must cast as Character ... aO[5] "C" Defaults to String -- Cannot cast as Character
aA[5] "C" Character returns Character ................. aO[5] "C" Defaults to String -- Cannot Test for Character

*/

异常显示为 cmets(上图)。

这是 Playground 输出:

aA: [a String, 123, -456.0, 0.330000013113022, false, C]

aA[0] is String:    a String
aA[1] is Int:       123
aA[2] is Double:    -456.0
aA[3] is Float:     0.330000013113022
aA[4] is Bool:      false
aA[5] is Not String: C
aA[5] is Character: C

aO: [a String, 123, -456, 0.33, 0, C]

aO[0] is String: a String
aO[1] is Int:    123
aO[2] is Double: -456
aO[3] is Float:  0.33
aO[4] is Bool:   0
aO[5] is String: C

【问题讨论】:

  • 您看到的一些异常是字符串插值实现方式的异常,而不是实际的转换差异。例如,布尔值被正确解释为 Bool 两次,只是由 println() 处理不同。
  • 谢谢!我刚试过 NSLog——但它不接受 Any 或 AnyObject 的 arg ...

标签: arrays swift


【解决方案1】:

您看到的异常是因为在基本 Swift 类型和基本 Objective-C 类型之间发生了一些隐式转换。例如,在 Swift 中,String 是一个结构体,因此不能添加到 AnyObject 数组中。但是,因为您正在导入 Foundation,所以它被隐式转换为 NSString,它是一个类,因此可以添加到 AnyObject 数组中。

另一方面,Character 没有转换为 Foundation 中可用的类。

不久前,我在blog post 中写了更多关于此的内容。

【讨论】:

  • 有趣...我按照您的建议返回并删除了 import Foundation ——它没有影响代码,但至少我知道幕后没有进行类型转换.我想知道我是否应该提交一个功能请求来添加特定的 Obj-C 类型转换并清理 Any 和 AnyObject 之间的一些异常——这似乎会消除很多混乱并产生更安全的代码。
  • @user2984842 你是否也删除了 UIKit 的导入?这也将导入 Foundation
  • @user2984842,当您删除 import Foundation import UIKit 时,您的代码会出现一堆编译器错误,因为隐式转换将不再可用。
  • 谢谢!我删除了 import UIKit——这破坏了 AnyObject——但 Any 仍然有效。
  • @user2984842,是的 Anyany 类型:)
猜你喜欢
  • 2014-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-16
  • 2018-08-23
  • 2021-01-30
相关资源
最近更新 更多