Swift 和变异结构

2024-03-22

当谈到 Swift 中的值类型变化时,我并不完全理解。

正如《Swift 编程语言》iBook 中所述:默认情况下,无法从其实例方法中修改值类型的属性。

为了使这成为可能,我们可以用mutating结构体和枚举中的关键字。

我不完全清楚的是: 您可以从结构体外部更改 var,但不能从其自身的方法更改它。这对我来说似乎违反直觉,因为在面向对象语言中,您通常尝试封装变量,以便只能从内部更改它们。对于结构体来说,情况似乎正好相反。为了详细说明,这里有一个代码片段:

struct Point {
    var x = 0, y = 0
    mutating func moveToX(x: Int, andY y:Int) { //Needs to be a mutating method in order to work
        self.x = x
        self.y = y
    }
}

var p = Point(x: 1, y: 2)
p.x = 3 //Works from outside the struct!
p.moveToX(5, andY: 5) 

有谁知道为什么结构不能从自己的上下文中更改其内容,而内容可以在其他地方轻松更改的原因?


可变性属性标记在存储(常量或变量)上,而不是类型上。你可以认为 struct 有两种模式:mutable and 不可变的。如果将结构体值分配给不可变存储(我们称之为let or constant在 Swift 中)该值变为不可变模式,并且您无法更改该值中的任何状态。 (包括调用任何变异方法)

如果该值被分配给可变存储(我们称之为var or variable在 Swift 中),你可以自由修改它们的状态,并且允许调用变异方法。

此外,类没有这种不可变/可变模式。 IMO,这是因为类通常用于表示可参考的实体。可引用实体通常是可变的,因为很难以不可变的方式创建和管理实体的引用图并具有适当的性能。他们可能会在以后添加此功能,但至少现在不会。

对于 Objective-C 程序员来说,可变/不可变的概念是非常熟悉的。在 Objective-C 中,每个概念都有两个独立的类,但在 Swift 中,您可以使用一个结构来完成此操作。一半工作。

对于C/C++程序员来说,这也是非常熟悉的概念。这正是constC/C++ 中的关键字 do。

此外,不可变值可以得到很好的优化。理论上,Swift 编译器(或 LLVM)可以对传递的值执行复制省略let,就像在 C++ 中一样。如果您明智地使用不可变结构,它将优于引用计数类。

Update

正如@Joseph 声称的那样,这并没有提供why,我补充一点。

结构体有两种方法。plain and mutating方法。Plain方法意味着不可变(或不可变)。这种分离的存在只是为了支持不可变的语义。处于不可变模式的对象根本不应该改变其状态。

那么,不可变方法必须保证这一点语义不变性。这意味着它不应该改变任何内部值。因此编译器不允许在不可变方法中对其自身进行任何状态更改。相反,变异方法可以自由修改状态。

然后,你可能会有一个疑问为什么默认是不可变的?这是因为很难预测变异值的未来状态,而这通常成为令人头痛和错误的主要来源。许多人同意解决方案是避免可变的东西,然后默认不可变几十年来,它一直是 C/C++ 家族语言及其派生语言的首选。

See 纯功能风格 http://en.wikipedia.org/wiki/Purely_functional更多细节。不管怎样,我们仍然需要可变的东西,因为不可变的东西有一些弱点,讨论它们似乎超出了主题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Swift 和变异结构 的相关文章

随机推荐

  • 为什么 Verilog 不被视为编程语言? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 教授在课堂上说学生不应该说他们学会了用Verilog 编程 他说 Verilog 之类的东西不是用来编程的 而是用来设计的 那么 Verilog
  • 摆脱“使用临时;使用文件排序”

    当我对我的查询进行解释时 我看到第一行的 额外 下有 使用临时 使用文件排序 我知道这很糟糕 但我不知道它到底意味着什么或如何解决它 如果您想查看我的查询 这是我针对同一查询提出的更普遍的问题 MySQL 查询优化和菜鸟解释 https s
  • 从 Ext.data.Store 访问 http 状态代码

    我有一个 http API 令人震惊的新技术 它对设置不同响应状态的不同错误做出反应 问题是 当使用 Ext data Store 和一些 XMLHttpRequest inside 代理时 处理这种状态的最佳方法是什么 据我所知 加载 事
  • 我可以根据时间更改背景颜色吗?

    我使用 html5 CSS bootstrap 创建了一个漂亮的网站 我想知道是否可以在白天 蓝色 和夜间 暗红色 期间在代码中自动更改背景颜色和导航栏选择颜色 我可以做些什么来根据用户的时间更改导航栏和背景的颜色吗 这是我的代码
  • C++:在小型项目的头文件中编写整个类的缺点?

    只是一个风格问题 我是一名独立工作的独立游戏开发者 我养成了在标题中编写整个类的 坏 习惯 我知道 h cpp 文件组合的一些好处是它们允许将代码分割成编译块 只要它们保持不变就不需要重新编译 并允许将接口与实现分开 然而 这些事情对我来说
  • Django-MPTT子页面的完整路径如何制作?

    我开始使用 Django MPTT 应用程序在我的 Django 站点页面上获取基于树的方法 对于前 我有带有子页面的页面 Trance 声音恍惚 子页 Hard Trance 子页面 Breaks Atmo Breaks 子页面 渐进式休
  • 创建独立于 bash 的进程

    我编写了一个程序来计算笔记本电脑中可用的电池电量 我还在程序中定义了一个阈值 每当电池电量低于阈值时 我想调用另一个进程 我使用了 system invoke o 其中 invoke o 是我必须运行的程序 我正在运行一个脚本 该脚本每 5
  • 在 zend 框架中运行控制器单元测试时出现“没有为此应用程序定义默认模块”异常

    我有一个具有默认目录结构的应用程序 对于没有自定义模块的应用程序 请参阅最后的结构图 我按照许多教程中的说明编写了一个 ControllerTestCase php 文件 并且还创建了相应的引导文件 再次参见最后的图 我已经编写了一些运行良
  • 处理双重间接时避免不兼容的指针警告

    假设这个程序 include
  • R 的 C API 中的 SEXP 数据类型到底是什么以及为什么使用它? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我知道关于 SEXP 的维基百科页面 并且我知道它代表符号表达 我 模糊地 知道 SEXP 是指 Lisp 中的树数据结构的符号 但我
  • 方向改变时 Activity 不断重新启动

    当屏幕旋转或用户在手机上滑动键盘时 如何防止活动重新启动 这可能吗 有解决办法吗 感谢所有相关答案 您可以通过在您的activity你的元素manifest xml 有问题的元素称为android configChanges 并且您需要注册
  • 上传错误:无法连接到 DataPusher。 ckan 2.4.3 中的错误

    我正在尝试将我的数据集上传到数据存储区 我创建数据集并尝试使用 ckan 界面中的 上传到数据存储 菜单将数据集上传到数据存储 我收到 上传错误 无法连接到 DataPusher Web 中的错误消息不在任何日志中 ckan 日志 data
  • 如何使用 RemoteViews 更新通知?

    我正在创建一个通知RemoteViews https d android com reference android widget RemoteViews从一个习惯Service 它在前台模式下以通知方式运行 也就是说 只要通知对用户可见
  • 根据另一列的相应行值创建行子集?

    让 CSV 包含两列 年龄 和 性别 其中 Age 30 24 55 61 70 21 Gender Male Female Male Male Male Female 我希望它向我显示与 Gender Male 相对应的所有 Age 值
  • R 从一个向量的最大值中提取 data.frame 的子集并按另一个向量分组[重复]

    这个问题在这里已经有答案了 gt ID lt c A A A B B B C C C C C gt WK lt c 1 2 3 1 2 3 1 2 3 4 5 gt NumSuccess lt c 0 0 2 0 0 1 0 0 0 0 3
  • 导出数组以在另一个 javascript 文件中使用

    在我的帖子请求中 我想检查是否thisString存在于另一个 javascript 文件数组中 Array js exports names John Mary Main js if names includes thisString d
  • jQuery UI 对话框关闭并没有清除对话框

    Using jQuery用户界面 http en wikipedia org wiki JQuery UI 我有一个选项卡插件 在选项卡 1 中加载了一个包含表格的页面 每行都有一个对话框的链接 一切正常 保存以下内容 对话框中有一个选项可
  • 在 Win32 程序中用 main() 函数替换 WinMain()

    我在 StackOverflow 和 Google 上进行了一些搜索 但没有找到答案 我想用这种类型的用户编程来启动我的应用程序 int main Window App Test 640 480 while App IsOpen Do th
  • JavaScript 变量作用域 [重复]

    这个问题在这里已经有答案了 我的一些 JavaScript 代码有问题 Script setTimeout function for var i 0 i lt 5 i setTimeout function console log i i
  • Swift 和变异结构

    当谈到 Swift 中的值类型变化时 我并不完全理解 正如 Swift 编程语言 iBook 中所述 默认情况下 无法从其实例方法中修改值类型的属性 为了使这成为可能 我们可以用mutating结构体和枚举中的关键字 我不完全清楚的是 您可