[英]Why can't the Swift compiler figure out the type of an element in a mixed-type array?
[英]Why does Swift Treat a Mixed Type Array as a Single Type Array Sometimes?
我最近开始学习Swift,并且对数组类型的处理方式有些困惑。
根据我的理解,数组中可以有不同的类型。 例如:
var arr = [1, 2, 3.0, 4, "myString"]
当我在XCode Playground中编写此代码并执行println()时,我得到了预期的输出:
[1, 2, 3.0, 4, "String"]
当我删除数组中的String时,得到以下输出:
[1.0, 2.0, 3.0, 4.0]
Swift为什么将整数视为双精度数? 当我在Playground中运行以下代码时,这使我有些困惑:
import UIKit
var arr = [2.0, 3, 4, 5]
for (index, value) in enumerate(arr) {
arr[index] = value / 2
}
我期望以下输出:
[1.0, 1, 2, 2]
但是输出是:
[1.0, 1.5, 2.0, 2.5]
为什么Swift会自动更改int的类型?
根据我的理解,数组中可以有不同的类型。
这种理解是不正确的,数组只能包含一种特定类型。
实际上,如果您在不包含任何其他内容的操场上键入原始示例(即删除“ import UIKit”或“ import Cocoa”语句),它将无法编译。
Swift标准库中的Array
结构如下所示:
struct Array<T> : MutableCollectionType, Sliceable {
// methods and properties
}
T
是“通用占位符”。 声明数组时,它将替换为数组包含的类型。 但是T
只能是一种。
当您声明变量而不指定类型时,Swift将尝试“推断”类型。 也就是说,它将从上下文中找出所有可能的类型,并根据(相当广泛的)一堆规则选择一个。
Double
和Int
都符合IntegerLiteralConvertible
协议。 这意味着您可以从诸如1
的文字中创建。 但是,默认为Int
。 如果要使用Double
,则需要明确。
// i will be an Int, the default
let i = 1
// j will also be an Int
let j: Int = 1
// k will be a Double
let k: Double = 1
Double
也符合FloatLiteralConvertible
,但Int
不符合:
// f will be a Double, the default:
let f = 1.0
// or you can declare a Float:
let g: Float = 1.0
// but this won’t work:
let h: Int = 1.0 // compiler error
声明数组时,Swift同样会尝试找出数组包含的T
类型。 它列出了所有可能性并选择了一种。 在[1.0, 1, 2]
的情况下,通过1.0
值排除了包含Int
的可能性,因此选择T == Double
。
同样,当您声明[1, 2, 3.0, 4, "String"]
,也会排除Double
。 唯一可行的类型是符合IntegerLiteralConvertible
, FloatLiteralConvertible
和StringLiteralConvertible
。 在各类标准斯威夫特库没有做到这一点。
那么为什么您的原始示例起作用? 当您导入UIKit时,它会NSObject
确实做到这一点的NSObject
类型。 因此Swift会选择它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.