【问题标题】:Why does Swift Treat a Mixed Type Array as a Single Type Array Sometimes?为什么 Swift 有时会将混合类型数组视为单一类型数组?
【发布时间】:2015-02-24 08:26:44
【问题描述】:

我最近开始学习 Swift,对数组中类型的处理方式有些困惑。

据我了解,数组中可以有不同的类型。例如:

var arr = [1, 2, 3.0, 4, "myString"]

当我在 XCode Playground 中编写此代码并执行 println() 时,我得到了预期的输出:

[1, 2, 3.0, 4, "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 会自动改变整数的类型?

【问题讨论】:

    标签: arrays swift types


    【解决方案1】:

    据我了解,数组中可以有不同的类型。

    这种理解是错误的,数组只能包含一种特定的类型。

    事实上,如果您将原始示例输入到包含其他内容的游乐场(即删除“import UIKit”或“import Cocoa”语句),它将无法编译。

    Swift 标准库中的Array 结构如下所示:

    struct Array<T> : MutableCollectionType, Sliceable {
        // methods and properties
    }
    

    T 是一个“通用占位符”。当您声明一个数组时,它会被替换为该数组包含的类型。但是T只能是一种类型。

    当你声明一个变量而不指定类型时,Swift 将尝试“推断”类型。也就是说,它会从上下文中找出所有可能的类型,并根据一组(相当广泛的)规则选择一个。

    DoubleInt 都符合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也被排除在外。唯一可行的类型是遵循IntegerLiteralConvertibleFloatLiteralConvertibleStringLiteralConvertible 的类型。 在标准的 Swift 类型库中没有能做到这一点。

    那么为什么您的原始示例有效?当你导入 UIKit 时,它会引入一个类型,NSObject,它确实做到了这一点。所以 Swift 选择了它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-07-26
      • 2021-12-15
      • 2014-04-28
      • 1970-01-01
      • 1970-01-01
      • 2016-10-18
      • 1970-01-01
      相关资源
      最近更新 更多