如何解决通过在 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 中改变变量(数组、散列等)是否有显着优势?
Array
和 Hash
是值,它们不是变量。 (虽然Array
是一个(常量)变量,它引用一个值,即表示数组概念的类Class
的实例.)
理解事物和名称之间的区别非常重要不仅在Ruby中,而且在一般编程(甚至超越编程)中都很重要 表示一个东西,或者一个盒子和盒子里面的东西。一双运动鞋与其交付的鞋盒不同,也与字母“Nike”不同。
那么,让我们看看这里的区别:
original_array = []
original_array << 'first'
这个例子中发生了什么?
- 您正在使用
Array
文字语法Array
创建一个新的值(一个作为[]
类实例的对象)。立> - 您正在创建一个名为
original_array
的新变量,并将其绑定到在第 1 步中创建的值。 - 您正在取消引用变量
original_array
(即向变量询问它绑定到的值)。立> - 您正在将消息
<<
发送到在第 3 步中获得的值。 - 为响应该消息而调用的方法的内部实现 mutates
self
,即作为消息接收方的值第 4 步。
[我省略了一些与理解无关的步骤,例如创建 String
值等。]
在任何时候你都没有改变变量 original_array
(在初始赋值之后)。在这段代码的末尾,该变量引用了它在开头所做的完全相同的值。
您确实改变了该变量引用的值。 (或者,更准确地说,您告诉值自行变异。)
现在,让我们将其与第二个片段进行比较:
original_array = []
original_array = original_array + ['first']
这里是第二个例子的比较[注意前三个步骤是相同的]:
- 您正在使用
Array
文字语法Array
创建一个新的值(一个作为[]
类实例的对象)。立> - 您正在创建一个名为
original_array
的新变量,并将其绑定到在第 1 步中创建的值。 - 您正在取消引用变量
original_array
(即向变量询问它绑定到的值)。立> - 您正在将消息
+
发送到在第 3 步中获得的值。 - 为响应该消息而调用的方法的内部实现返回一个新的、不同的、单独的、独特的值。
- 您正在重新绑定变量
original_array
到在第 5 步中创建的新值。
在任何时候你都没有改变在第 1 步中创建的值。
你做到了但是改变了变量 original_array
。
所以,在某种意义上,这两个片段完全是双重(在该术语的范畴理论意义上):
- 变量不变,值变化。
- 变量变异,值不变。
“不变性”是否是一个合适的概念来描述这一点?
这两个例子都不是一成不变的。它们中的任何一个都改变了something,第一个改变了值,第二个改变了变量。
不可变版本如下所示:
original_array = []
new_array = original_array + ['first']
请注意,通常变异变量和变异值同样糟糕。事实上,值(对象)是由它们的实例变量组成的,所以改变实例变量就是改变它们所属的值(对象)。
“不良程度”本质上是一个范围问题。范围越有限,越不坏,越容易理解和控制。
就您而言,您有一个局部变量。局部变量具有局部作用域(本质上是一个方法体、一个(可能嵌套的)块或 lambda 体、一个模块/类体或一个脚本体)。希望您的方法足够小,以便您可以跟踪和跟踪局部变量的所有用法和所有变化。
另一方面,改变一个值会产生更远的后果。在银河系的一个完全独立的部分中的一些完全独立的代码段也可能使用同一个对象,如果你对这个对象进行变异,他们也会看到变异的版本。理解这种“幽灵般的远距离动作”要困难得多。本质上,改变由两段代码共享的值会将这两段代码紧密耦合在一起。
改变实例变量介于两者之间。是的,您正在更改可能对多个其他代码段可见的内容的状态。但是,只有允许对象本身改变其实例变量,其他人不能这样做。 [再次,忽略反射。] 因此,大概是因为有人明确告诉它改变了它自己的实例变量,并且该对象将确保其所有记录和指定的不变量仍然有效。此外,希望对象可能会自身发生变异这一事实被清楚地记录在案,这样客户就不会对此感到惊讶。
我们可以尝试推导出一些通用规则:
- 您可以改变自己(您的实例变量),前提是这不会改变外部可见的记录行为。
- 您可以改变自己并更改您在外部可见的记录行为,前提是行为可能会发生变化以及此特定方法可能会改变行为的事实已明确记录。
- 你可以改变你创建的对象(更准确地说,告诉对象改变自己),前提是你永远不要把这个对象交给其他人。
- 您可以对自己创建的对象进行变异,并在完成变异后将其交给其他人。
- 您不得改变您分发给其他人的对象。
- 你不得改变别人交给你的对象。
- 您可以改变局部变量,前提是作用域足够小以清楚地了解正在发生的事情。
- 您绝对不能使用类变量,它们的范围很混乱,而且比您想象的要大得多。
- 您不得改变全局变量。
- 你不能改变常量。 (是的,它是 Ruby 允许的,并且“只会”生成一个警告,但这只是令人困惑,因为程序员期望常量是……呃……常量。)
这可能看起来有限制,但考虑到像 Haskell 这样的语言,规则很简单:你不能变异。任何事物。曾经。 (事实上,你不能,该语言甚至没有能力。)然而,我们可以使用 Haskell 构建与使用任何其他语言一样强大的系统。 >
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。