为什么不可能有这个:
def main(args:Array[String]) {
val whatever:String // Have it uninitialized here
if(someCondition) {
whatever = "final value" // Initialize it here
}
}
Run Code Online (Sandbox Code Playgroud)
我不明白为什么这不合法.我知道我可以做到var,但为什么我们必须val在我们宣布它时准确地初始化它?以后能够初始化它似乎更合乎逻辑吗?
阅读C#深度,第2版,第2.1.2节关于组合和删除代表.
小节标题指出"代表是不可改变的",并且"关于它们的任何内容都不能改变".但是,在下一段中,它讨论了使用类似的结构
x += y;
Run Code Online (Sandbox Code Playgroud)
where x和y是兼容委托类型的变量.
我没有改变x吗?或者不变性部分是否处理何时x处理(即,立即)?
这只是"我想知道......"问题中的一个.
Scala具有不可变数据结构和(可选)惰性值等.
Scala程序与完全纯粹(在函数编程意义上)和完全懒惰(或Ingo指出,它是否足够非严格)的程序有多接近?哪些价值观不可避免地变得多变,什么评价不可避免地贪婪?
这是简短的版本.首要的是:我希望我的班级不变.我知道一堂课既不是抽象的,也不是最终的.我要问的是:有没有办法只允许内部类扩展和实现外部的抽象类?这可能不是实现我不可改变的目标的最佳方法,所以如果有人有更好的设计,我很乐意听到它.
我正在为矢量运算编写一个类 - 如物理和工程,而不是编程意义.(我也知道JScience有这个东西的包.我想写自己的,并保持简单.)
我喜欢Java几何包中使用的模式,其中,例如,a Line2D可以使用两个精度级别之一创建:float或double.
public abstract class Line2D {
public static class Float extends Line2D { /* Implementation */ }
public static class Double extends Line2D { /* Implementation */ }
}
Run Code Online (Sandbox Code Playgroud)
这是我真的想在课堂上加入和扩展的功能,所以我创建了以下内容:
public abstract class Vector2D {
public final static class Integer extends Vector2D {
// Component length projected along x/y axis, respectively
final private int i, j;
public Integer( int i, int j ) {
this.i = …Run Code Online (Sandbox Code Playgroud) 有以下课程:
public class Member {
private int x;
private long y;
private double d;
public Member(int x, long y, double d) {
this.x = x;
this.y = y;
this.d = d;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + x;
result = (int) (prime * result + y);
result = (int) (prime * result + Double.doubleToLongBits(d));
return result;
}
@Override
public boolean equals(Object obj) {
if (this …Run Code Online (Sandbox Code Playgroud) 我在周日下午摆弄着,正试图创造一种"房间"结构.基本上,一个Room对象有许多出口,每个出口都指向其他Room的出口.现在,我要创建的第一件事是两个Room相互连接,最好是在一个赋值语句中.像这样:
case class Room(title: String, exits: Map[Direction.Direction, Room])
val firstRoom = Room("A room", Map(North -> Room("Another room", Map(South -> firstRoom))))
Run Code Online (Sandbox Code Playgroud)
Ergo:第一个房间有一个出口North到第二个房间,第二个房间有一个出口South回到第一个房间.
但是,正如您可以想象的那样,这是错误的:firstRoom在创建val时未定义val,因此在分配期间尝试引用它将不起作用.
对于大多数(如果不是全部)编程语言,我很确定这是正确的.我的问题:如何在不使我的Room对象变为可变的情况下解决这个问题?我可以简单地创建一些Room对象并在之后添加出口,但这使得Rooms 变得可变,并且作为个人练习我试图避免这种情况.
我正在阅读Joshua Bloch撰写的有效Java第15项.在第15项中谈到"最小化可变性"时,他提到了使对象不可变的五条规则.其中之一就是让所有领域都是最终的.这是规则:
使所有字段成为最终字段:这清楚地以系统强制执行的方式表达您的意图.此外,如果对新创建的实例的引用在没有同步的情况下从一个线程传递到另一个线程,则必须确保正确的行为,如内存模型中所述[JLS,17.5; Goetz06 16].
我知道String类是一个不可变类的例子.通过源代码我看到它实际上有一个非最终的哈希实例.
//Cache the hash code for the string
private int hash; // Default to 0
Run Code Online (Sandbox Code Playgroud)
String如何成为不可变的呢?
我想ImmutableLinkedHashMap<>在Guava库中找到类似的东西.我需要使用带有插入顺序的不可变键值数据结构.那么,我该怎么用?
虽然我明白改变价值String.Empty会是一个坏主意,但我不明白为什么我不能这样做.
为了得到我的意思,请考虑以下课程:
public class SomeContext
{
static SomeContext(){}
public static readonly string Green = "Green";
public static readonly SomeContext Instance = new SomeContext();
private SomeContext(){}
public readonly string Blue = "Blue";
public static void PrintValues()
{
Console.WriteLine(new { Green, Instance.Blue, String.Empty }.ToString());
}
}
Run Code Online (Sandbox Code Playgroud)
我有一个小的控制台应用程序,试图操纵这三个只读字段.它可以成功地将蓝色和绿色变成粉红色,但是Empty保持不变:
SomeContext.PrintValues();
/// prints out : { Green = Green, Blue = Blue, Empty = }
typeof(SomeContext).GetField("Blue").SetValue(SomeContext.Instance, "Pink");
typeof(SomeContext).GetField("Green", BindingFlags.Public | BindingFlags.Static).SetValue(null, "Pink");
typeof(String).GetField("Empty", BindingFlags.Public | BindingFlags.Static).SetValue(null, "Pink");
SomeContext.PrintValues();
/// prints out : { …Run Code Online (Sandbox Code Playgroud) 我正在使用immutability helper更新React状态的数组中的对象.
我想要修改的对象是嵌套的:
this.state = {
a: {
b: [{ c: '', d: ''}, ...]
}
}
Run Code Online (Sandbox Code Playgroud)
我想使用immutability helper更新b的第n个元素中的prop c.
没有不变性助手的等效代码是:
const newState = Object.assign({}, this.state);
newState.a = Object.assign({}, newState.a);
newState.a.b = newState.a.b.slice();
newState.a.b[n] = Object.assign({}, newState.a.b[n]);
newState.a.b[n].c = 'new value';
this.setState({ newState });
Run Code Online (Sandbox Code Playgroud)
我知道上面的代码有点难看.我假设使用immutability helper的代码将解决我的问题.谢谢
immutability ×10
java ×4
scala ×3
c# ×2
.net ×1
constants ×1
delegates ×1
guava ×1
hashcode ×1
hashset ×1
javascript ×1
reactjs ×1
reflection ×1
string ×1