当我们谈论字符串是可变的时,这是使用"可更改"或"可修改"这个词的同义词还是有一些额外的细微差别来解释为什么使用这个术语而不是像"可修改"这样的简单词?
我想问一下mutable的使用是否合适:
#include <iostream>
class Base
{
protected:
int x;
public:
virtual void NoMod() const
{
std::cout << x << std::endl;
}
void Draw() const
{
this->NoMod();
}
};
class Derive : public Base
{
private:
mutable int y;
public:
void NoMod() const
{
y = 5;
}
};
int main()
{
Derive derive;
// Test virtual with derive
derive.Draw();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Base类是第三方库.我正在扩展它以提供我自己的NoMod().库原始NoMod()声明为const.
我的NoMod()与Base的不同之处在于它需要修改自己的成员变量.
因此,对于我自己的NoMod()来编译并在调用Draw()时调用,我必须这样做
1)实现Derive :: NoMod()作为const
2)使我的int y可变.
这是我能做的最好的吗?
在Java中,我可以执行以下操作:
TreeMap<Double, String> myMap = new TreeMap<Double, String>();
Run Code Online (Sandbox Code Playgroud)
如果我希望它以相反的顺序排序,我可以提供一个比较器,例如:
class ReverseOrder implements Comparator<Object> {
public ReverseOrder() {
}
public int compare(Object o1,Object o2) {
Double i1=(Double)o1;
Double i2=(Double)o2;
return -i1.compareTo(i2);
}
}
Run Code Online (Sandbox Code Playgroud)
并将对象实例化为
TreeMap<Double, MyObject> myMap = new TreeMap<Double, MyObject>()(new ReverseOrder());
Run Code Online (Sandbox Code Playgroud)
如果我想从Scala中创建可变的Java TreeMap,我可以这样做:
var treeMap = new java.util.TreeMap[Double,MyObject]
Run Code Online (Sandbox Code Playgroud)
如何在Scala中实现Java比较器,以便我可以根据升序或降序进行排序?在这里,我假设我不能将Scala Ordering特征与Java集合混合.另外,有没有人知道Scala中是否可以使用可变的TreeMap?
这个关于Haskell的主题讨论了很多(例如可变数组实现),但我仍然不确定需要频繁修改和随机访问数组/向量的情况的最佳实践是什么.
说一个长度为1,000,000的向量.对其进行操作涉及基于输入访问其(小的,例如1000个)子集,并基于输入修改值.此外,这种操作重复2,000,000次.任务本身可以在纯数据结构中实现,例如列表,如下所示,尽管效率很低:
type Vect = [Int]
f :: Vect -> [[Int]] -> Vect
f x indsList = foldl g x indsList
-- g is just an example of random-access and modifications on the values.
g :: Vect -> [Int] -> Vect
g x inds = map h $ zip x [0..]
where h (x, i) = if i `elem` inds then x !! i + 1 else x !! i
Run Code Online (Sandbox Code Playgroud)
散列/映射数据结构(例如IntMap)可以用于有效的大量随机访问,但是数组/向量也应该这样做.更重要的是,仍需要通过可变结构来解决大量修改以避免存储器复制.Haskell中是否存在可变的随机访问数组/向量?如果使用ST/IO Monads,这些控件会影响我的设置吗?
我想将一个可变映射转换为封闭范围内的不可变映射.以下是情况和无意义防御副本的示例代码:
def func(): immutable.Map[String, Int] = {
val map = mutable.HashMap[String, Int]
// here goes operations for the map
return immutable.HashMap ++ map
}
Run Code Online (Sandbox Code Playgroud)
当我写"无意义"时,在这里做防御性复制完全是浪费,因为可变地图实际上是从外部不可变的.如果我们只能从外部看到getter操作,那么性能应该更好.
问题是我真的不知道该怎么做.我试过用匿名的不可变映射实例简单地包装它,但是这个方法def +[B1 >: B](kv: (A, B1))使它变得不可能.
请帮我!
编辑:刚才忘了修复返回类型[Int, Int]来[String, Int]
TL; DR:
如何确保给定语句中randomRIO(from System.Random)生成的值的持久性do?
如何使用IO Monad中的可变结构?
我最初的问题是(非常)错误 - 我正在更新标题,以便将来想要理解在IO monad中使用可变结构的读者可以找到这篇文章.
更长的版本:
抬头:这看起来很长,但很多只是我概述了如何exercism.io运作.(更新:最后两个代码块是我的代码的旧版本,作为参考,以防未来的读者希望根据评论/答案跟随代码中的迭代.)
练习概述:
我正在Robot Name从(非常有教育意义的)exercism.io开始练习.练习涉及创建一个Robot能够存储名称的数据类型,该名称是随机生成的(练习Readme包括在下面).
对于那些不熟悉它的人,exercism.io学习模型基于学生生成的代码的自动测试.每个练习都包含一系列测试(由测试作者编写),解决方案代码必须能够通过所有测试.我们的代码必须通过给定练习的测试文件中的所有测试,然后我们才能进入下一个练习 - 一个有效的模型,imo.(Robot Name运动#20左右.)
在这个特殊的练习中,我们会要求创建一个Robot数据类型和三个附带功能:mkRobot,robotName和resetName.
mkRobot 生成一个实例 Robot robotName生成并"返回"未命名的唯一名称Robot(即,robotName不覆盖预先存在的名称); 如果Robot已有名称,则只返回现有名称resetName 用新的名称覆盖预先存在的名称.在这个特定的练习中,有7个测试.测试检查:
robotName生成符合指定模式的名称(名称长度为5个字符,由两个字母后跟三个数字组成,例如AB123,XQ915等)robotName是持久性的(即,假设我们创建机器人A并使用它来为他(或她)分配名称robotName; robotName第二次调用(在机器人A上)不应该覆盖他的名字)robotName为不同的机器人生成唯一的名称(即,它测试我们实际上是随机化过程)resetName生成符合指定模式的名称(类似于测试#0)resetName是持久的我正在尝试动态建立一棵树,并在下降,叶子和备份期间修改树的某些部分。我相信我对在Rust中如何做这样的事情有根本的误解。这是我的代码:
struct Node {
children: Vec<Node>,
data: usize,
}
impl Node {
pub fn new() -> Node {
Node {
children: vec![],
data: 0,
}
}
pub fn expand(&mut self) {
self.children = vec![Node::new(), Node::new()];
}
pub fn is_leaf(&self) -> bool {
self.children.len() == 0
}
}
pub fn main() {
let mut root = Node::new();
for _ in 0..10 {
let mut node = &mut root;
let mut path = vec![];
// Descend and potential modify the node in …Run Code Online (Sandbox Code Playgroud) 我试图在一个循环中获得一个可变的借用,我无法让它工作.我已经尝试了所有可能的守卫,原始指针,一切.
struct Test<'a> {
a: &'a str,
}
impl<'a> Test<'a> {
pub fn new() -> Self {
Test { a: &mut "test" }
}
pub fn dostuff(&'a mut self) {
self.a = "test";
}
pub fn fixme(&'a mut self) {
let mut i = 0;
while i < 10 {
self.dostuff();
i += 1;
}
}
}
fn main() {
let mut test = Test::new();
test.fixme();
}
Run Code Online (Sandbox Code Playgroud)
error[E0499]: cannot borrow `*self` as mutable more than once at a time
--> …Run Code Online (Sandbox Code Playgroud) MVector有两种口味,IOVector和STVector.我想编写一些使用的函数STVector,这样即使使用快速可变矢量算法也可以从纯代码中调用它们Data.Vector.Algorithms.
在相关主题的帮助下,我已经Vector到了那里:我可以将一个不可变的东西粘在一个可变的ST上下文中:
import Control.Monad.ST
import Data.Vector
import Data.Vector.Algorithms.Intro (sort)
x = fromList [1,4,2] :: Vector Int
verboseCopy :: Vector Int
verboseCopy = runST $ do v <- thaw x
freeze v
Run Code Online (Sandbox Code Playgroud)
我只需要sort在解冻和冻结之间运行.
也许令人惊讶的是,我没有必要import Data.Vector.Mutable,这STVector是定义的地方.也许我应该使用类型签名来指定我想要thaw生成一个STVector,但我不知道如何:如果我将thaw行更改为:
v <- thaw x :: Data.Vector.Mutable.STVector s Int
Run Code Online (Sandbox Code Playgroud)
我收到此错误:
• Couldn't match expected type ‘MVector
(primitive-0.6.3.0:Control.Monad.Primitive.PrimState (ST s))
Int’ …Run Code Online (Sandbox Code Playgroud) 我的应用程序使用了可变的自定义元素集。一旦我崩溃了,并发生了错误“在Set中发现重复元素”。插入后元素可能已经突变。”
在寻找解释时,我发现了这篇帖子,我对此并不完全了解。
我的印象是,不应修改集合的元素,因为这也会修改集合的哈希值,因此进一步的访问可能会失败。
我的问题:
编辑:
用不同的措词表述:修改可变集合的自定义元素的属性而不修改集合本身是否安全?