通过在 Ruby 中就地修改变量与重新分配,可以获得什么?

如何解决通过在 Ruby 中就地修改变量与重新分配,可以获得什么?

在 ruby​​ 中,可以通过以下方式之一更新数组:

        import { Dialog } from 'react-native-simple-dialogs';
        import RNExitApp from 'react-native-exit-app';
        import Updater from '../Updater';
        import { ActivityIndicator,Alert } from 'react-native';
          constructor(props) {
            super(props);
            this.state = {
              progressVisibility: false,downloadVisibility: false,downloadBar: "",}
          }
          componentDidMount() {
            console.disableYellowBox = true;
            const self = this;
        
            function onStart(progress) {
              self.setState({downloadVisibility: true})
              self.setState({downloadBar: progress})
            }
        
            function onComp() {
              self.setState({downloadVisibility: false})
              Alert.alert('Dikkat!','Gelen güncellemeyi yüklemeden işlem yapamazsınız. Yükleme işlemini başlatmadıysanız,uygulamayı kapatıp açarak tekrar deneyiniz.',[{ text: "Kapat",onPress: () => RNExitApp.exitApp() }])
            }
            Updater(onStart,onComp);
          }

第二种形式有优势吗?我问是因为它“感觉”是不可变的,但知道变量只是重新分配了让我认为它只提供了一个更长的语句并使用了更多的内存。

与此同时,其他语言的不变性经历使我对original_array = [] original_array << 'first' # or original_array = [] original_array = original_array + ['first'] 产生负面反应。

在 Ruby 中改变变量(数组、散列等)是否有显着优势?从“不可变”操作重新分配相同的变量是否有优势? “不变性”是否是一个合适的概念来描述这一点?

解决方法

就地版本 x << y 在扩展现有对象时具有更高的内存效率。这减少了垃圾收集器的压力。

使用 x = x + [ y ]x += [ y ] 的替代方法效率要低得多,在这种情况下,您要创建一个非常短暂的临时数组,然后将其附加到一个新数组,然后丢弃旧数组.

您应该使用就地修改除非以下一项或多项条件适用:

  • 不应更改数组,因为它不是您“拥有”的参数
  • 数组被冻结并且无法更改

差异会根据您执行的操作数量而放大。如果您正在执行大量追加操作,则将它们累积在追加缓冲区中可能是有意义的,将它们一次性添加如下:

y = [ ] 
z.each do |a|
  # Example with processing
  y << a
end

x = x.concat(y)

尽管这些都是高度情境化的。

,

您的主要困惑似乎是您混淆了变量和值。变量和值是根本不同的,并且是从根本上分离的概念,几乎所有编程语言从未遇到过事物和事物的名称不是同一件事!

在你的主题行中写下[粗体强调我的]:

在 Ruby 中就地修改变量与 重新分配相比,可以获得什么?

这没有意义。在 Ruby 中有唯一一种修改变量的方法:赋值。除了分配给它之外,不可能以任何其他方式修改变量。时期。 [除了通过反射,但一旦你允许反射,无论如何,一切都会消失,所以我通常会忽略它。]

因此,询问“某事分配”没有意义,因为没有替代“某事”不是您可以将分配与分配进行比较的分配.

同样,在你写的问题正文中:

在 Ruby 中改变变量(数组、散列等)是否有显着优势?

ArrayHash,它们不是变量。 (虽然Array 一个(常量)变量,它引用一个值,即表示数组概念的类Class的实例.)

理解事物名称之间的区别非常重要不仅在Ruby中,而且在一般编程(甚至超越编程)中都很重要 表示一个东西,或者一个盒子和盒子里面的东西。一双运动鞋与其交付的鞋盒不同,也与字母“Nike”不同。

那么,让我们看看这里的区别:

original_array = []
original_array << 'first'

这个例子中发生了什么?

  1. 您正在使用 Array 文字语法 Array 创建一个新的(一个作为 [] 类实例的对象)。立>
  2. 您正在创建一个名为 original_array 的新变量,并将其绑定到在第 1 步中创建的
  3. 您正在取消引用变量 original_array(即向变量询问它绑定到的)。立>
  4. 您正在将消息 << 发送到在第 3 步中获得的
  5. 为响应该消息而调用的方法的内部实现 mutates self,即作为消息接收方的第 4 步。

[我省略了一些与理解无关的步骤,例如创建 String 值等。]

在任何时候你都没有改变变量 original_array(在初始赋值之后)。在这段代码的末尾,该变量引用了它在开头所做的完全相同的值。

确实改变了该变量引用的。 (或者,更准确地说,您告诉值自行变异。)

现在,让我们将其与第二个片段进行比较:

original_array = []
original_array = original_array + ['first']

这里是第二个例子的比较[注意前三个步骤是相同的​​]:

  1. 您正在使用 Array 文字语法 Array 创建一个新的(一个作为 [] 类实例的对象)。立>
  2. 您正在创建一个名为 original_array 的新变量,并将其绑定到在第 1 步中创建的
  3. 您正在取消引用变量 original_array(即向变量询问它绑定到的)。立>
  4. 您正在将消息 + 发送到在第 3 步中获得的
  5. 为响应该消息而调用的方法的内部实现返回一个新的、不同的、单独的、独特的值
  6. 您正在重新绑定变量 original_array 到在第 5 步中创建的新值

在任何时候你都没有改变在第 1 步中创建的

做到了但是改变了变量 original_array

所以,在某种意义上,这两个片段完全是双重(在该术语的范畴理论意义上):

  1. 变量不变,变化
  2. 变量变异不变。

“不变性”是否是一个合适的概念来描述这一点?

这两个例子都不是一成不变的。它们中的任何一个都改变了something,第一个改变了,第二个改变了变量

不可变版本如下所示:

original_array = []
new_array = original_array + ['first']

请注意,通常变异变量和变异值同样糟糕。事实上,值(对象)是由它们的实例变量组成的,所以改变实例变量就是改变它们所属的值(对象)。

“不良程度”本质上是一个范围问题。范围越有限,越不坏,越容易理解和控制。

就您而言,您有一个局部变量。局部变量具有局部作用域(本质上是一个方法体、一个(可能嵌套的)块或 lambda 体、一个模块/类体或一个脚本体)。希望您的方法足够小,以便您可以跟踪和跟踪局部变量的所有用法和所有变化。

另一方面,改变一个值会产生更远的后果。在银河系的一个完全独立的部分中的一些完全独立的代码段也可能使用同一个对象,如果你对这个对象进行变异,他们也会看到变异的版本。理解这种“幽灵般的远距离动作”要困难得多。本质上,改变由两段代码共享的值会将这两段代码紧密耦合在一起。

改变实例变量介于两者之间。是的,您正在更改可能对多个其他代码段可见的内容的状态。但是,只有允许对象本身改变其实例变量,其他人不能这样做。 [再次,忽略反射。] 因此,大概是因为有人明确告诉它改变了它自己的实例变量,并且该对象将确保其所有记录和指定的不变量仍然有效。此外,希望对象可能会自身发生变异这一事实被清楚地记录在案,这样客户就不会对此感到惊讶。

我们可以尝试推导出一些通用规则:

  • 您可以改变自己(您的实例变量),前提是这不会改变外部可见的记录行为。
  • 您可以改变自己并更改您在外部可见的记录行为,前提是行为可能会发生变化以及此特定方法可能会改变行为的事实已明确记录。
  • 你可以改变你创建的对象(更准确地说,告诉对象改变自己),前提是你永远不要把这个对象交给其他人。
  • 您可以对自己创建的对象进行变异,并在完成变异后将其交给其他人。
  • 不得改变您分发给其他人的对象。
  • 不得改变别人交给你的对象。
  • 您可以改变局部变量,前提是作用域足够小以清楚地了解正在发生的事情。
  • 绝对不能使用类变量,它们的范围很混乱,而且比您想象的要大得多。
  • 不得改变全局变量。
  • 不能改变常量。 (是的,它是 Ruby 允许的,并且“只会”生成一个警告,但这只是令人困惑,因为程序员期望常量是……呃……常量。)

可能看起来有限制,但考虑到像 Haskell 这样的语言,规则很简单:你不能变异。任何事物。曾经。 (事实上​​,你不能,该语言甚至没有能力。)然而,我们可以使用 Haskell 构建与使用任何其他语言一样强大的系统。 >

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-