为啥我需要在 Swift 的类中指定变量的类型?

Posted

技术标签:

【中文标题】为啥我需要在 Swift 的类中指定变量的类型?【英文标题】:Why do I need to specify what type a variable is in a class in Swift?为什么我需要在 Swift 的类中指定变量的类型? 【发布时间】:2014-06-03 03:19:04 【问题描述】:

我只是想知道。据我了解,varlet 可以是任何东西,Swift 会像javascript 那样自动执行正确的类型。但是,当我尝试在类中设置属性时,如果我没有指定类型,则会出现错误。

var value1, value2 // Error: missing annotations

好吧,我已经阅读了一些参考资料,并且该变量需要声明类型,例如 var foo = 0。但是在我的班级中,我有一个init(),它将变量设置为我在创建班级对象时输入的任何内容。

那么我应该如何实现呢?有可能吗?

我看到了 typealias 类型,但也没有用。

【问题讨论】:

@Ben-G 有一个很好的答案。但请记住,您也需要在 (Obj)C 中为变量声明类型... 【参考方案1】:

虽然 Swift 和 Javascript 都允许您在不定义变量类型的情况下将常量分配给变量,但两种语言之间存在根本区别。 Swift 是一种强类型、类型安全的语言,而 Javascript 不是。来自 Swift 编程语言 -

“Swift 是一种类型安全的语言。类型安全的语言鼓励你 清楚你的代码可以使用的值的类型。如果部分 你的代码需要一个字符串,你不能错误地传递一个 Int。”

摘自:Apple Inc. “Swift 编程语言”。电子书。 https://itunes.apple.com/au/book/swift-programming-language/id881256329?mt=11

所以当你说

var welcomeMessage = "Hello" 

Swift 推断您希望welcomeMessage 是一个字符串并相应地设置它的类型。随后尝试

welcomeMessage=3

将给运行一个编译时错误,因为您分配了不正确的类型。

如果您不分配初始值,那么 Swift 无法推断类型,您必须指定它。

另一方面,Javascript 会很乐意接受

var welcomeMessage="Hello"
welcomeMessage=3

因为它不是类型安全的,只是试图用它所拥有的值做到最好。例如,如果对welcomeMessage 赋值3 后对其进行字符串操作,Javascript 会将值转换为“3”,然后执行该操作。

虽然 Javascript 有类型安全的扩展,但它不像 Swift 那样是语言的基本部分

【讨论】:

JavaScript 是类型安全的。 “类型安全”意味着您不能误解内存中的字节。当你在 JavaScript 中操作一个值时,如果存在类型问题,它要么成功,要么抛出一个语言错误。 “Typesafe”并不表示源码中是否有明确的类型声明。 根据 Apple 在他们的书中给出的定义,标准 JavaScript 不是类型安全的——因为 JavaScript 是松散类型的,您可以通过在需要数字的地方传递任意字符串来获得运行时错误。 Swift 将在编译时检测到这一点并报告错误,导致构建失败。 Swift 既是类型安全的又是强类型的。 JavaScript 是类型安全的,但不是强类型的。苹果的书不是正式的,是口语的。它是有意的口语化,因为如果它是正式的,大多数目标观众将无法理解它。在引用的特定段落中,它们本来可以是正式的并且仍然可以理解,但它们总体上选择了非正式的。 更正:当你说“强类型”时,你真正的意思是“静态类型”。即,您的意思是编译器将发出有关类型的错误。 “静态”与“动态”表明我们是在谈论编译时还是运行时。 “强”与“弱”表示您是否可以误解数据。 C 是静态类型的,但是弱类型,例如,您可以隐式强制丢失数据。【参考方案2】:

只有在您最初指定默认值时才会推断类型。从语言参考中的示例中,要么声明类型:

var welcomeMessage: String

或分配一个允许 Swift 推断类型的初始值:

welcomeMessage = "Hello"

在上面的welcomeMessage示例中,没有提供初始值,因此welcomeMessage变量的类型是通过类型注释指定的,而不是从初始值推断出来的。

【讨论】:

我想知道var welcomeMessage: String的默认值是多少 @Andraw 没有默认值。如果您不提供初始化程序,则必须编写 init 并在那里初始化变量。唯一的例外是可选项(不需要初始化,因为......它们是可选的)。【参考方案3】:

JavaScript 是动态类型的,这意味着变量没有类型分配给它们。类型仅与对象相关联。所以一个变量可以包含任何类型的对象。

另一方面,Swift 是 静态 类型的。意思是变量有类型。您不能将任何您想要的对象放入变量中。编译器会确保您只将兼容的对象放入变量中。

Swift 有类型推断,如果你写的话,它允许编译器找出类型:

var value1 = "foobar"

但是仅仅写var value1 不会让编译器弄清楚value1 变量是什么类型。 JavaScript 没有这个问题,因为变量没有类型。

请记住,看起来相似的语法并不意味着相同的语义。 Swift 可能看起来有点像 JavaScript 语法,但关键字的含义(语义)却大不相同。如果你想模拟 JavaScript:

var value1, value2

在 Swift 中你会这样写:

var value1: AnyObject
var value2: AnyObject

这将允许您将任何对象放入 value1value2 变量中。

【讨论】:

以上是关于为啥我需要在 Swift 的类中指定变量的类型?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我们需要在 bindParam() 中指定参数类型?

为啥必须在 ES2015 中指定导出的类型(let、var、const...)?

为啥要在 ASM 中指定变量的地址而不是将其复制到寄存器中?

如何在函数中指定参数在 Swift 中可以为零

如何在 map 函数中指定数据类型?

final