我一直在脑子里反复思考,而且我似乎无法想出为什么C#闭包是可变的.如果您不知道究竟发生了什么,这似乎是一种获得意想不到的后果的好方法.
也许一个知识渊博的人可以阐明为什么C#的设计者会允许状态在闭包中改变?
例:
var foo = "hello";
Action bar = () => Console.WriteLine(foo);
bar();
foo = "goodbye";
bar();
Run Code Online (Sandbox Code Playgroud)
这将为第一个呼叫打印"hello",但外部状态在第二个呼叫时改变,打印"再见".更新了闭包的状态以反映局部变量的更改.
由于某种原因,我正在迭代一个类的元素,std::set并希望稍微修改键,知道订单将保持不变.
迭代器std::set是const_iterators因为如果修改了密钥,则可能导致订单错误,从而导致设置损坏.但是我确信我的操作不会改变集合中元素的顺序.
目前,这是我的解决方案:
class Foo
{
public:
Foo(int a, int b): a_(a),b_(b) {}
~Foo(){}
bool operator < (const Foo& o) const { return this.a_ < o.a_ ; }
void incrementB() const { ++b_; } // <-- the problem: it is not const!
private:
const int a_;
mutable int b_; // <-- I would like to avoid this
}
void f()
{
std::set<Foo> s;
// loop and insert many (distinct on a_) Foo elements;
std::for_each(s.begin(), …Run Code Online (Sandbox Code Playgroud) 如果你需要在D中重写以下C++代码,你会怎么做?
struct A{
const S* _s;
B _b;
C _c;
mutable C _c1, _c2;
A(const B& b, const C& c, const S* s){ /*...*/ }
void compute(const R& r) const
{
//...
_c1 = ...
_c2 = ...
}
};
Run Code Online (Sandbox Code Playgroud)
D没有mutable,而且根据我的经验,它很少用于C++.但是,假设mutable在这里使用正确的原因,我在D中的选择是什么?
我需要在Ocaml中使用可变变量的哈希表,但它没有用.
let link = Hashtbl.create 3;;
let a = ref [1;2];;
let b = ref [3;4];;
Hashtbl.add link a b;;
# Hashtbl.mem link a;;
- : bool = true
# a := 5::!a;;
- : unit = ()
# Hashtbl.mem link a;;
- : bool = false
Run Code Online (Sandbox Code Playgroud)
有没有办法让它有效?
在Objective-C中是否有用于实现可变/不可变对象类对的标准模式?我目前有类似以下内容,我根据此链接编写
不可变类:
@interface MyObject : NSObject <NSMutableCopying> {
NSString *_value;
}
@property (nonatomic, readonly, strong) NSString *value;
- (instancetype)initWithValue:(NSString *)value;
@end
@implementation MyObject
@synthesize value = _value;
- (instancetype)initWithValue:(NSString *)value {
self = [self init];
if (self) {
_value = value;
}
return self;
}
- (id)mutableCopyWithZone:(NSZone *)zone {
return [[MyMutableObject allocWithZone:zone] initWithValue:self.value];
}
@end
Run Code Online (Sandbox Code Playgroud)
可变类:
@interface MyMutableObject : MyObject
@property (nonatomic, readwrite, strong) NSString *value;
@end
@implementation MyMutableObject
@dynamic value;
- (void)setValue:(NSString *)value {
_value = value; …Run Code Online (Sandbox Code Playgroud) 我正在阅读Scala编程,第2版(精彩的书,比scala的网站更好,以非摇滚科学的方式解释事物),我注意到这......在回到不可变和可变的时候很奇怪集.
它将以下内容声明为不可变集
var jetSet=Set("Boeing", "Airbus")
jetSet+="Lear"
println(jetSet.contains("Cessna"))
Run Code Online (Sandbox Code Playgroud)
然后声明只有Mutable集定义了+ =方法.好吧,这很有道理.问题是这段代码有效.在REPL中测试时创建的集合类型实际上是不可变集合,但它上面定义了+ =方法,并且它的功能非常好.看哪
scala> var a = Set("Adam", "Bill")
a: scala.collection.immutable.Set[String] = Set(Adam, Bill)
scala> a += "Colleen"
scala> println(a)
Set(Adam, Bill, Colleen)
scala> a.getClass
res8: Class[_ <: scala.collection.immutable.Set[String]] = class scala.collection.immutable.Set$Set3
Run Code Online (Sandbox Code Playgroud)
但是如果我声明Set为val,则创建的Immutable Set 没有定义+ =方法
scala> val b = Set("Adam", "Bill")
b: scala.collection.immutable.Set[String] = Set(Adam, Bill)
scala> b += "Colleen"
<console>:9: error: value += is not a member of scala.collection.immutable.Set[String]
b += "Colleen"
Run Code Online (Sandbox Code Playgroud)
这里发生了什么?它们都被声明为一个不可变的Set,但声明var可以访问+ =方法并且可以使用它.
另外,当我继续在var Immutable Set上调用getClass方法时,我发现了一些奇怪的东西....
scala> a.getClass
res10: Class[_ …Run Code Online (Sandbox Code Playgroud) 我需要使我的可变类不可变,现在它看起来如下.但是,我仍然不确定我是否有一个完全"不可变的*类,如果是这样,那么这个叫做什么样的不变性?
public class B<C, M>
where C : IComparable<C>
where M : IMetaData
{
internal B(char tau, M metadata, B<C, M> nextBlock)
{
if (tau == 'R') omega = 1;
_lambda = new List<Lambda<C, M>>();
_lambda.Add(new Lambda<C, M>(tau: tau, atI: metadata));
foreach (var item in nextBlock.lambda)
if (item.tau != 'L')
_lambda.Add(new Lambda<C, M>(tau: 'M', atI: item.atI));
}
internal int omega { private set; get; }
private List<Lambda<C, M>> _lambda { set; get; }
internal …Run Code Online (Sandbox Code Playgroud) 有人可以解释这两者之间的区别是什么时候mut a: &T最常用的?
我有这样的C结构:
struct my_struct {
int i;
double d;
struct expensive_type * t;
};
Run Code Online (Sandbox Code Playgroud)
创建此结构的实例并将其初始化为:
struct my_struct * my_new( int i , double d)
{
struct my_struct * s = malloc( sizeof * s);
s->i = i;
s->d = d;
s->t = NULL;
return s;
}
Run Code Online (Sandbox Code Playgroud)
计算struct expensive_type * t成员是非常昂贵的,可能不需要 - 它只是初始化为NULL- 然后根据需要计算:
const struct expensive_type * my_get_expensive( const struct my_struct * s)
{
if (!s->t)
s->t = my_expensive_alloc( s->i , s->d );
return s->t;
}
Run Code Online (Sandbox Code Playgroud)
在C++中,我会用 …
我正在使用tokio-rs在Rust中构建一个服务,并且对这个技术堆栈感到满意.我现在正试图将包含写入的异步操作和借用检查器的困难时间联系起来.
我简化的最小代码示例如下:
extern crate futures; // 0.1.21
use futures::Future;
use std::{cell::RefCell, rc::Rc};
trait RequestProcessor {
fn prepare(&self) -> Box<Future<Item = (), Error = ()>>;
fn process(&mut self, request: String) -> Box<Future<Item = (), Error = ()>>;
}
struct Service {
processor: Rc<RefCell<RequestProcessor>>,
}
impl Service {
fn serve(&mut self, request: String) -> Box<Future<Item = (), Error = ()>> {
let processor_clone = self.processor.clone();
let result_fut = self
.processor
.borrow()
.prepare()
.and_then(move |_| processor_clone.borrow_mut().process(request));
Box::new(result_fut)
}
}
fn main() {}
Run Code Online (Sandbox Code Playgroud)
作为一个简短的总结,在异步准备步骤之后,我正在尝试运行另一个写入字段的异步操作 …
mutable ×10
c# ×2
immutability ×2
rust ×2
set ×2
asynchronous ×1
c ×1
c++ ×1
class-design ×1
closures ×1
const ×1
d ×1
future ×1
hashtable ×1
ios ×1
objective-c ×1
ocaml ×1
reference ×1
rust-tokio ×1
scala ×1
subclassing ×1