解决的办法是作弊一点。特别:
这可以显式完成(在C ++中为示例):
struct List {
int n;
List *next;
List(int n, List *next)
: n(n), next(next);
};
// Return a list containing [0,1,0,1,...].
List *binary(void)
{
List *a = new List(0, NULL);
List *b = new List(1, a);
a->next = b; // Evil, but necessary.
return a;
}
或隐式(例如Haskell中的示例):
binary :: [Int]
binary = a where
a = 0 : b
b = 1 : a
Haskell示例使用惰性评估来实现相互依赖的不可变值的错觉。值开始为:
a = 0 : <thunk>
b = 1 : a
a
和b
都是独立有效的正常形式。可以构造每个缺点,而无需其他变量的最终值。当评估thunk时,它将指向相同的数据b
指向。
因此,如果要使两个不可变值相互指向,则必须在构造第二个值后更新第一个值,或者使用更高级别的机制来执行相同操作。
在您的特定示例中,我可以在Haskell中将其表示为:
data Material = Water {temperature :: Double}
| Ice {temperature :: Double}
setTemperature :: Double -> Material -> Material
setTemperature newTemp (Water _) | newTemp <= 0.0 = Ice newTemp
| otherwise = Water newTemp
setTemperature newTemp (Ice _) | newTemp >= 1.0 = Water newTemp
| otherwise = Ice newTemp
但是,我回避了这个问题。我想象过,在一种面向对象的方法中,将一个setTemperature
方法附加到每个Material
构造函数的结果中,您将必须使构造函数指向彼此。如果将构造函数视为不可变值,则可以使用上面概述的方法。
h2o
材料