允许访问者修改Receiver的状态或者应该是Command模式通常是否可以接受?
我对f#中变量的肤浅理解表明,将变量声明为"可变"并使用"ref"变量基本上都做同样的事情.它们是解决相同基础问题的不同方式 - 功能语言中有限且结构化的可变性允许,而不必求助于IO Monad.我的理解已经"抽象"了技术上的不同.
我很抱歉,如果这是一个多人,但他们似乎都相关.
我遇到了Java并发问题.是的,我看了几乎完全相同标题的问题,但他们似乎都在寻求微妙的不同之处.是的,我已经阅读了Java Concurrency in Practice.是的,我能看到为什么它是事实上的对话题参考.是的,我已经阅读了专门针对线程安全类中的发布字段的部分.是的,我仍然会问一个关于Java的并发问题,不管我知道有人会简单地指出我那本书.
这让我很难过 - 我知道你可以通过确保具有易变性和/或同步访问的正确读/写命令,以线程安全的方式轻松发布可变原语字段,并且64位原语需要具有原子访问权限由于其读/写操作缺乏原子性.我知道在需要在类的字段的特定"快照"上执行的代码块上使用锁.我完全了解原子包和AtomicLong <>等好东西.
但是我仍然对将非线程安全对象作为线程安全类中的字段发布感到困惑.
从我所看到的,一旦你在getter中返回对它的引用,你就可以在任何时候对调用者提供前所未有的对象内容访问权限.此外,如果你给一个setter,你允许他们将对象引用设置为一个对象,它们可以在他们使用setter的对象之外控制它们.
无论如何,我无法解决从非线程安全对象组成线程安全类而不使它们全部私有/受保护并在类中为所有非线程安全对象创建所有非线程安全对象的线程安全包装器方法让该类的用户可能想要使用.这听起来像是一个样板噩梦.
我的意思是,如果你将一个AtomicReference <>返回给getter中的对象,他们可以使用.get()来再次获得对它的非同步访问.
我考虑的另一种方法是让所有getter基于旧的获取非线程安全对象的新副本,这意味着修改将是无关紧要的,同样适用于setter.但是Java有一个无可救药的复杂系统来克隆对象(浅拷贝与深拷贝与特定拷贝等),这有点让我无法做到这一点.而且,这是如此低效,以至于它不会比使用像Clojure那样为不变性而设计的语言更快.事实上,考虑到这些语言允许多条不可变数据在幕后共享相同的数据,它可能会慢得多.
那么,如何以可行的方式编写已发布的非线程安全对象的线程安全类?
提前致谢.
我在模块中有一组需要访问某些共享初始化时间状态的函数.实际上,我想用静态可变矢量来模拟这个:
static mut defs: Vec<String> = vec![];
fn initialize() {
defs.push("One".to_string());
defs.push("Two".to_string());
}
Run Code Online (Sandbox Code Playgroud)
(示例:http://is.gd/TyNQVv,失败,"可变静态不允许有析构函数".)
我的问题类似于是否可以在Rust中使用全局变量?,但使用a Vec(即带有析构函数的类型),因此Option基于该问题的解决方案似乎不适用.也就是说,这失败的错误与我的第一次尝试相同:
static mut defs: Option<Vec<String>> = None;
fn initialize() {
let init_defs = vec![];
init_defs.push("One".to_string());
init_defs.push("Two".to_string());
defs = Some(init_defs);
}
Run Code Online (Sandbox Code Playgroud)
有没有办法访问在初始化时填充并在运行时可见的静态("全局")向量?
是否有其他模式我应该考虑支持这个用例?传递对状态向量的显式引用是可能的,但会混乱大量的函数签名,这些函数签名都需要访问此状态.
的Objective-C运行保持声明的属性作为元数据与一个类对象的列表.元数据包括属性名称,类型和属性.运行时库还提供了一些函数来检索这些信息.这意味着声明的属性不仅仅是一对存取方法(getter/setter).我的第一个问题是:为什么我们(或运行时)需要元数据?
众所周知,在子类中不能覆盖声明的属性(readwrite与readonly除外).但我有一个场景,保证需要:
@interface MyClass : MySuperClass <NSCopying, NSMutableCopying>
@property (nonatomic, copy, readonly) NSString *string;
- (id)initWithString:(NSString *)aString;
@end
@interface MyMutableClass : MyClass
@property (nonatomic, strong, readwrite) NSMutableString *string;
- (id)initWithString:(NSString *)aString;
@end
Run Code Online (Sandbox Code Playgroud)
当然,编译器不会让上面的代码通过.我的解决方案是使用一对存取方法替换声明的属性(使用readonly case,只是getter):
@interface MyClass : MySuperClass <NSCopying, NSMutableCopying> {
NSString *_string;
}
- (id)initWithString:(NSString *)aString;
- (NSString *)string;
@end
@implementation MyClass
- (id)initWithString:(NSString *)aString {
self = [super init...];
if (self) {
_string = [aString copy];
}
return self;
}
- (NSString *)string {
return …Run Code Online (Sandbox Code Playgroud) 当我注意到一个可变字段用^:unsynchronized-mutable注释时,我正在研究一个clojure lib .Mutable是可变的,但我不知道未同步的部分意味着什么,所以我读了文档,其中包含:
请注意,可变字段非常难以正确使用,并且只是为了便于在Clojure本身中构建更高级别的构造,例如Clojure的引用类型.它们仅供专家使用 - 如果:volatile-mutable或:unynchronized-mutable的语义和含义对您来说不是很明显,那么您就不应该使用它们.
我无法得到细微差别:它是否说在实践中我选择哪个可变性注释无关紧要,或者人们应该忘记完全使用可变类型?
并且,为了好奇,在较低的抽象层次中,它们之间的语义差异是什么?
谢谢!
可变性是特征中的通用参数吗?我想为一个类型的可变和不可变变量实现一个特征,而不必复制和粘贴该impl块.
trait Foo<T> {…}
impl<T> Foo for *const T {…}
impl<T> Foo for *mut T {…same thing again…}
一厢情愿的伪代码:
trait Foo<T> {…}
impl<T, Mutability> Foo for *Mutability T {…}
请考虑以下代码(Playground版本):
use std::cell::Cell;
struct Foo(u32);
#[derive(Clone, Copy)]
struct FooRef<'a>(&'a Foo);
// the body of these functions don't matter
fn testa<'a>(x: &FooRef<'a>, y: &'a Foo) { x; }
fn testa_mut<'a>(x: &mut FooRef<'a>, y: &'a Foo) { *x = FooRef(y); }
fn testb<'a>(x: &Cell<FooRef<'a>>, y: &'a Foo) { x.set(FooRef(y)); }
fn main() {
let u1 = Foo(3);
let u2 = Foo(5);
let mut a = FooRef(&u1);
let b = Cell::new(FooRef(&u1));
// try one of the following 3 statements
testa(&a, &u2); …Run Code Online (Sandbox Code Playgroud) 我来自C#世界,曾经习惯于将数组作为引用类型。据我了解,快速数组中的是值类型,但它们试图充当参考值。
我实际上不知道如何问自己需要什么(我认为这是当我需要知道答案才能提出问题时的情况),但是在C#中,我会说我需要存储对a的内部数组的引用锯齿状数组变成局部变量。
考虑以下代码:
// a function to change row values in-place
func processRow(inout row : [Int], _ value : Int)
{
for col in 0..<row.count
{
row[col] = value;
}
}
// a function to change matrix values in-place
func processMatrix(inout matrix : [[Int]])
{
for rowIdx in 0..<matrix.count
{
// (1) Works with array in-place
processRow(&(matrix[rowIdx]), -1)
// (2) Creates local copy
var r = matrix[rowIdx]; // <--- What to write here to not make a copy but still …Run Code Online (Sandbox Code Playgroud) 我有一个结构:
pub struct Test {
pub x: i32,
pub y: i32,
}
Run Code Online (Sandbox Code Playgroud)
我想要一个改变这个的功能 - 简单:
pub fn mutateit(&mut self) {
self.x += 1;
}
Run Code Online (Sandbox Code Playgroud)
这使得整个结构在函数调用的持续时间内是可变的,对mutateit吗?我只是想发生变异x,而我不希望发生变异y.有没有办法可以随意借用x?
mutability ×10
rust ×4
accessor ×1
arrays ×1
c# ×1
clojure ×1
closures ×1
composition ×1
concurrency ×1
f# ×1
java ×1
objective-c ×1
static ×1
struct ×1
swift ×1
traits ×1