整个程序可以是不可变的吗? [关闭]

2024-06-11

  • 我熟悉不可变性并且可以设计不可变类,但我主要拥有学术知识,缺乏实践经验
  • 请参考上面的链接图片(尚不允许嵌入)
  • 从下往上看
  • 学生需要新地址
  • 我们并没有真正改变学生,而是创建一个包含新地址的新学生
  • mutator 方法返回这个新对象

Question:假设变异器调用来自不可变对象,如何处理这个新对象?

  • 新学生无法保存在 Lecture 中,因为 Lecture 也是不可变的
  • 所以我们还需要一个新的讲座,其中包含新的学生
  • 但是在哪里保存新的讲座呢?
  • 当然是在新学期,但它在哪里结束呢?
  • 至少可以通过使用组件外观模式来打破该链,该模式处理所有新对象的创建,而不必通过整个链转发调用

Question: 到哪里停呢?是否必须在某个地方有一个可变对象才能至少保存最顶层的实例?


这就是函数式编程的思想。一切都是不可变的,任何函数调用都不允许有副作用。改变复杂对象的唯一方法(如您的示例中)是重新创建父对象。

现在的问题是如何改变程序状态。因此,我们首先想到的是栈。它包含所有局部变量的值以及被调用函数的所有参数的值。我们可以通过调用新函数来创建新值。我们可以通过从函数返回来丢弃值。因此,我们可以通过调用函数来改变程序状态。然而,并不总是可以从函数返回来丢弃其局部变量,因为我们可能只想丢弃一些局部变量,但需要保留其他局部变量的值以供进一步操作。在这种情况下,我们根本无法返回,但我们需要调用另一个函数并仅将一些局部变量传递给它。现在,为了防止堆栈溢出,函数式语言有一个称为尾调用优化的功能,它能够从调用堆栈中删除不必要的条目。如果关联函数唯一需要做的事情就是返回自身调用的函数的值,则不需要调用堆栈条目。在这种情况下,保留调用堆栈条目是没有意义的。通过删除不必要的调用堆栈条目,其他未使用的局部变量的值将被丢弃。您可能想阅读相关内容here https://en.wikipedia.org/wiki/Tail_call. Also, 尾递归 https://stackoverflow.com/questions/33923/what-is-tail-recursion与此有关。

同样,这是纯函数式编程语言的想法,例如Haskell https://www.haskell.org/。一切都是不可变的,这真的很好,但是这些语言有它们唯一的问题和它们自己的处理这些问题的方法。例如,Monad(以及更高种类的类型)在这些语言中可用,但在命令式/面向对象编程语言中很少见到。

我喜欢在程序内存的叶子上有不可变的值。但是,组成这些不可变值(实际上形成应用程序逻辑)的代码确实包含可变状态。对我来说,这结合了两个世界的优点。然而,这似乎是一个偏好问题。

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

整个程序可以是不可变的吗? [关闭] 的相关文章

  • 展开字符串中的环境变量

    是否有一些 java 实用程序 可以扩展 和 env 字符串中的变量 就像 bin MY PATH gt home john bin dev null 谢谢 基本上 您想要使用环境变量进行字符串插值并扩展主目录 我不知道执行后者的简单方法
  • 模拟匿名函数

    我正在编写 jUnits 但被 Lambda 表达式困住了 有没有办法模拟匿名函数 return retryTemplate execute retryContext gt return mockedResponse 在上面的代码中 我试图
  • CompletableFuture:几个任务

    如何使用 5 个 CompletableFutures 异步执行 20 个 Runnable 任务 或 1 个任务 20 次 这就是我所拥有的 Runnable task gt long startTime System currentTi
  • 以行和列模式打印字符串 Java

    我刚刚创建了一个java项目来打印在行和列中给出的字符串 就像矩阵一样 这是我刚刚制作的输出 h e l l o w o r l d i t s b e a u t i f u l 是否可以将输出显示为像这样的螺旋图案 h e l l o
  • 如何使用流从两个列表或数组乘法中查找元素对

    我有两个数字列表 我想找到所有可能的数字对 例如 给定列表 1 2 3 and 3 4 结果应该是 1 3 1 4 2 3 2 4 3 3 3 4 我知道我可以使用for loop但有没有更简洁的方法来使用Java 8 流 我尝试了以下操作
  • PowerMock,模拟静态方法,然后对所有其他静态调用真实方法

    我正在设置模拟类的静态方法 我必须在 Before 带注释的 JUnit 设置方法 我的目标是设置类来调用真正的方法 except对于那些我明确嘲笑的方法 基本上 Before public void setupStaticUtil Pow
  • PHP Socket Java 消息交换

    我正在尝试在 PHP 页面和正在运行的 Java 服务器之间进行通信 只是通过套接字进行简单的字符串交换 这是我处理连接的线程的 Java 代码 InputStream in clientSocket getInputStream Buff
  • gradlew:appengineEnhance 失败

    我正在使用 Java 创建移动后端Google App Engine with Android Studio 为了启动公开我的 API 的本地服务器 我使用gradlew module name appengineRun 然而 当我去htt
  • 使用带有 OnException 定义的adviceWith进行Camel路由测试

    我有一个非常简单的 Camel 路由定义 其中只包含一些 OnException 谓词来处理相应的异常和一些日志语句 from hazelcast seda someQueue id someQueueID onException Cust
  • IBM Websphere JPA 配置 - 如何更新 persistence.xml

    我是 EJB 3 和 JPA 的新手 我在应用程序服务器中创建了一个数据源 它是jdbc AppDataSource 默认持久性提供程序保留为com ibm websphere persistence PersistenceProvider
  • 使用超类创建构建器时,父类无法返回子类的实例[重复]

    这个问题在这里已经有答案了 如果我使用构建器模式来配置新对象 我可能有两个类 例如Game and HockeyGame 如下所示 当我想创建一个新的HockeyGame 我得到它的构建器并开始调用方法来根据需要配置对象 我遇到的问题显示在
  • 如何在java中模拟SHIFT+鼠标按键

    我想将鼠标指针移动到特定位置并执行 SHIFT 鼠标右键单击 我可以将鼠标移动到某个位置 但无法模拟鼠标单击 Robot r new Robot r mouseMove x1 y1 我应该做什么来模拟预期的鼠标点击 我认为您只需要一点额外的
  • 我怎样才能设置在中间呢?

    我尝试用Java画一个矩形 我设置了框架大小 800 400 和可调整大小 假 矩形的x 50 y 50宽度 700高度 300 为什么它不在中间 谢谢 如果没有任何其他证据 我会guess你已经覆盖了paint类似的方法JFrame并直接
  • 跨不同的类访问 @BeforeTest 和 @AfterClass (TestNG) 中的变量?

    我正在使用 Java 和 TestNG 框架为我的公司编写一些 selenium 自动化 UI 测试 我正在定义驱动程序Base类 我想在一个中实际初始化驱动程序 BeforeTest并退出它 AfterTest方法 假设它们位于不同的类中
  • 将 OraclePreparedStatement 与 DBCP 连接结合使用

    我正在尝试使用 dbcp 框架为我的 oracle 服务器创建一个连接池 我用过这个tutorial http web archive org web 20120615100115 http www freshblurbs com 80 j
  • Maven“部署”导致签名操作后代码重新打包(BAD 签名)

    我想将一个工件部署到 Sonatype OSS 存储库 当我使用以下命令进行部署时 签名无效 mvn clean source jar javadoc jar install gpg sign deploy gt gpg verify ta
  • JPA:如何在不加载延迟加载集的情况下计算子记录数

    我正在编写一个 J2EE JPA Spring 3 应用程序 试图保持纯粹的 JPA 2 0 我想获得子对象的计数而不必加载它们 因为这显然是一个昂贵的操作 例如 这是一个简化的示例 Organisation OrgID OrgName E
  • Protobuf RPC 在 Hadoop 2.2.0 单节点服务器上不可用?

    我正在尝试在按照本教程安装的本地单节点集群上运行 hadoop 2 2 0 mapreduce 作业 http codesfusion blogspot co at 2013 10 setup hadoop 2x 220 on ubuntu
  • Java 1.4 有泛型吗?

    查看 Java 1 4 中的一些旧代码 但我对 Java 不熟悉 Java 1 4 有泛型吗 我一直在查看代码 没有发现泛型的任何用途 但这并不一定意味着它们不受支持 不 那是 1 5 的介绍 即 Java 2 发行版 1 5 really
  • 逆变方法参数类型

    wiki 逆变方法参数类型 https en wikipedia org wiki Covariance and contravariance 28computer science 29 Contravariant method argum

随机推荐

  • 在 '*' 标记之前编译“错误:预期 ')' 时出现多个相同错误

    我正在尝试用 C 语言编程 当我使用以下参数进行编译时 gcc D BSD SOURCE Wall ansi pedantic g tokenizer c FileOccur c WordList c wordstat c indexer
  • 使用与 eval 相反的括号表示法

    我有以下内容 var module function console log module ran var someString module string TypeError object is not a function eval s
  • 设计在 XHR 上抛出 HTTP 身份验证并注销

    我在使用 Devise 使用 OmniAuth 来验证我的 Rails 应用程序时遇到很多问题 我重新启动我的服务器并在隐身模式下打开一个新选项卡 以便清除 cookie 并加载我的应用程序 我登录 然后进入该应用程序 当我到达通过 AJA
  • Exec 战前目标存档包

    我想在打包战争之前运行 maven replacer plugin 我找到了 准备包 阶段 但它在战争组装和复制所有资源之前触发 但我需要在复制所有资源时和创建存档之前进行更改 这在maven中可能吗 顺便说一句 我使用 maven 2 2
  • 如何检查应用程序的 .NET 版本?

    除了在仅具有 NET Framework 版本 3 5 的计算机上运行之外 如何检查 NET 应用程序的版本 NET 框架版本控制在 NET 2 0 之后变为 foobar 一个应用程序的目标是CLR版本 它使用 EXE 的程序集元数据来实
  • Toast.LENGTH_LONG 和 Toast.LENGTH_SHORT 的值是多少?

    我正在我的应用程序中打印 Toast 消息以显示通知 但我想知道 Toast LENGTH LONG 和 Toast LENGTH SHORT 我还可以使用哪些其他值 谁能告诉我这两个变量的值是多少 还有另一个问题可以回答您正在寻找的内容
  • 核心数据推导表达式关键路径使用运算符作为中间组件

    我正在尝试编写一对多关系属性之和的派生表达式 我有一个商品和一个组 该商品有价格和总价 金额 价格 我想编写一个表达式 将该组的总价格作为其组成部分的总和 当我构建时出现错误 错误 属性配置错误 LAEItemGroup totalPric
  • MailChimp 取消订阅 URL 中每个参数的用途是什么?

    在以下 URL 中 从列表中取消订阅用户 http xxxxx us2 list manage com unsubscribe u 87f537bccxx35e53a1890e0d9 id 40dcxx6cd6 e c4aaxx1dd6 c
  • Numpy:查找两个 3-D 数组之间的欧几里德距离

    给定两个维度为 2 2 2 的 3 D 数组 A 0 0 92 92 0 92 0 92 B 0 0 92 0 0 92 92 92 如何有效地找到 A 和 B 中每个向量的欧几里得距离 我尝试过 for 循环 但速度很慢 而且我正在按 g
  • 从一个 NSManagedObjectContext 保存的更改不会反映在主 NSManagedObjectContext 上

    我有一个主NSManagedObjectContext是在appDelegate 现在 我正在使用另一个NSManagedObjectContext用于编辑 添加新对象而不影响主对象NSManagedObjectContext 直到我拯救它
  • 就地改变 numpy 函数输出数组

    我正在尝试编写一个对数组执行数学运算并返回结果的函数 一个简化的例子可以是 def original func A return A 1 A 1 为了加速并避免为每个函数调用分配新的输出数组 我希望将输出数组作为参数 并就地更改它 def
  • 将 Swift 闭包作为值添加到 Swift 字典中

    我想创建一个 Swift 字典 将 String 类型作为其键 将 Closures 作为其值 以下是我的代码 但它给了我错误 lvalue 与 String gt Void 不同 class CommandResolver private
  • 用 C# 解析和查询 SOAP

    我正在尝试解析一个大量命名空间的 SOAP 消息 源也可以在here http tinyurl com n3av6k
  • 如何解决 Xcode 7 中的 No Type or Protocol Named 错误?

    我试图passing从第二个开始的值class我正在使用的头等舱protocol and delegate过程 每当我运行我的程序时 我都会遇到以下问题 No Type or Protocol Named locateMeDelegate
  • 理解“窗口”对象[重复]

    这个问题在这里已经有答案了 可能的重复 JS 窗口全局对象 https stackoverflow com questions 10035771 js window global object 如何window对象工作 我知道它是顶级对象并
  • Liftweb 环境中的后台任务

    我必须编写守护进程 并且我想使用模型来连接到数据库和一些有用的 Lift 类 是否可以运行 Rails 的 rake 任务的模拟 Scala 社区组上也有类似的问题 答案是使用Actors来做后台处理
  • 转储 Windows DLL 版本的命令行工具?

    我需要一个命令行工具来转储标准 Windows DLL 版本信息 以便我可以通过 bash 脚本 Cygwin 对其进行处理 作为一名 Java 开发人员 我不太习惯 Microsoft 开发工具 尽管我对 Microsoft Visual
  • 使用 pytz 获取时区的国家/地区代码?

    我在用着pytz http pytz sourceforge net country information 我已经阅读了整个文档表 但没有看到如何做到这一点 我有一个时区 美国 芝加哥 我想要的只是获取该时区的相应国家 地区代码 美国 它
  • rspec 在需要存根的私有方法中测试私有方法

    Simplecov 检测到我遗漏了一些测试lib api verson rb class class ApiVersion def initialize version version version end def matches req
  • 整个程序可以是不可变的吗? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我熟悉不可变性并且可以设计不可变类 但我主要拥有学术知识 缺乏实践经验 请参考上面的链接图片 尚不允许嵌入 从下往上看 学生需要新地址