天道酬勤,学无止境

.NET中可能有不可变的数组吗?(Are immutable arrays possible in .NET?)

问题

是否有可能以某种方式将System.Array标记为不可变。 当放在公共获取/私有集后面时,由于需要重新分配和重新分配,因此不能将它们添加到其中,但是消费者仍然可以设置他们希望的任何下标:

public class Immy
{
    public string[] { get; private set; }
}

我以为readonly关键字可以解决问题,但是没有这种运气。

回答1

ReadOnlyCollection <T>可能是您要寻找的。 它没有Add()方法。

回答2

框架设计指南建议返回数组的副本。 这样,消费者就无法更改数组中的项目。

// bad code
// could still do Path.InvalidPathChars[0] = 'A';
public sealed class Path {
   public static readonly char[] InvalidPathChars = 
      { '\"', '<', '>', '|' };
}

这些更好:

public static ReadOnlyCollection<char> GetInvalidPathChars(){
   return Array.AsReadOnly(InvalidPathChars);
}

public static char[] GetInvalidPathChars(){
   return (char[])InvalidPathChars.Clone();
}

这些示例直接来自于本书。

回答3

请参阅基类库中的“不可变集合现在可用”(当前在预览中)。

回答4

您可以使用Array.AsReadOnly方法返回。

回答5

出于这个确切的原因,我相信最佳实践是在公共API中使用IList <T>而不是数组。 readonly将阻止在构造函数之外设置成员变量,但是正如您所发现的那样,不会阻止人们在数组中分配元素。

有关更多信息,请参见认为有害的阵列。

编辑:数组不能是只读的,但是可以将它们通过Array.AsReadOnly()转换为只读的IList实现,如@shahkalpesh所指出的那样。

回答6

除了最简单和最传统的用例外,.NET往往都远离阵列。 对于其他所有内容,都有各种枚举/集合实现。

当您要将一组数据标记为不可变时,您将超越传统数组提供的功能。 .NET提供了等效的功能,但从技术上讲不是以数组的形式提供的。 要从数组中获取不可变的集合,请使用Array.AsReadOnly <T>:

var mutable = new[]
{
    'a', 'A',
    'b', 'B',
    'c', 'C',
};

var immutable = Array.AsReadOnly(mutable);

immutable将是ReadOnlyCollection <char>实例。 作为更一般的用例,您可以从任何常规IList <T>实现中创建ReadOnlyCollection <T>。

var immutable = new ReadOnlyCollection<char>(new List<char>(mutable));

注意,它必须是通用的实现。 普通的旧IList将不起作用,这意味着您不能在仅实现IList的传统数组上使用此方法。 这揭示了使用Array.AsReadOnly <T>作为获得对通常无法通过传统数组访问的通用实现的访问的快速方法的可能性。

ReadOnlyCollection <T>将使您能够访问不可变数组期望的所有功能:

// Note that .NET favors Count over Length; all but traditional arrays use Count:
for (var i = 0; i < immutable.Count; i++)
{
    // this[] { get } is present, as ReadOnlyCollection<T> implements IList<T>:
    var element = immutable[i]; // Works

    // this[] { set } has to be present, as it is required by IList<T>, but it
    // will throw a NotSupportedException:
    immutable[i] = element; // Exception!
}

// ReadOnlyCollection<T> implements IEnumerable<T>, of course:
foreach (var character in immutable)
{
}

// LINQ works fine; idem
var lowercase =
    from c in immutable
    where c >= 'a' && c <= 'z'
    select c;

// You can always evaluate IEnumerable<T> implementations to arrays with LINQ:
var mutableCopy = immutable.ToArray();
// mutableCopy is: new[] { 'a', 'A', 'b', 'B', 'c', 'C' }
var lowercaseArray = lowercase.ToArray();
// lowercaseArray is: new[] { 'a', 'b', 'c' }
回答7

唯一要添加的是数组暗示可变性。 从函数返回Array时,是在向客户端程序员建议他们可以/应该进行更改。

回答8

除了Matt的回答,IList是数组的完整抽象接口,因此它允许添加,删除等。我不确定为什么Lippert似乎建议将其作为需要不变性的IEnumerable的替代方案。 (编辑:因为IList实现可以为那些变异方法抛出异常,如果您喜欢的话)。

可能要记住的另一件事是,列表中的项目也可能具有可变状态。 如果您确实不希望调用者修改这种状态,则可以选择以下选项:

确保列表中的项目是不可变的(例如您的示例:字符串是不可变的)。

返回所有内容的深层克隆,因此在这种情况下,您仍然可以使用数组。

返回一个接口,该接口提供对项目的只读访问权限:

interface IImmutable
{
    public string ValuableCustomerData { get; }
}

class Mutable, IImmutable
{
    public string ValuableCustomerData { get; set; }
}

public class Immy
{
    private List<Mutable> _mutableList = new List<Mutable>();

    public IEnumerable<IImmutable> ImmutableItems
    {
        get { return _mutableList.Cast<IMutable>(); }
    }
}

请注意,可以从IImmutable接口访问的每个值本身必须是不可变的(例如,字符串),或者是您即时生成的副本。

回答9

您希望做的最好的事情就是扩展现有的馆藏以建立自己的馆藏。 最大的问题是,它的工作方式必须不同于每个现有的集合类型,因为每个调用都必须返回一个新的集合。

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • Java中的不可变数组(Immutable array in Java)
    问题 在Java中,有没有一成不变的替代原始数组的方法? 将原始数组定为final实际上并不能阻止人们做类似的事情 final int[] array = new int[] {0, 1, 2, 3}; array[0] = 42; 我希望数组的元素不可更改。 回答1 不适用于原始数组。 您将需要使用列表或其他数据结构: List<Integer> items = Collections.unmodifiableList(Arrays.asList(0,1,2,3)); 回答2 我的建议是不要使用数组或不可unmodifiableList而要使用为此目的而存在的番石榴的ImmutableList。 ImmutableList<Integer> values = ImmutableList.of(0, 1, 2, 3); 回答3 正如其他人指出的那样,Java中不能有不可变的数组。 如果您绝对需要一个返回不影响原始数组的数组的方法,那么您每次都需要克隆该数组: public int[] getFooArray() { return fooArray == null ? null : fooArray.clone(); } 显然,这是相当昂贵的(因为每次调用getter都会创建一个完整副本),但是如果您不能更改界面(例如使用List ),并且不能冒险让客户更改内部结构,那么可能有必要。
  • JavaScript字符串是不可变的吗? 我需要JavaScript中的“字符串生成器”吗?(Are JavaScript strings immutable? Do I need a “string builder” in JavaScript?)
    问题 JavaScript是否使用不可变或可变的字符串? 我需要一个“字符串生成器”吗? 回答1 他们是一成不变的。 您不能使用var myString = "abbdef"; myString[2] = 'c'类的内容来更改字符串中的字符var myString = "abbdef"; myString[2] = 'c' var myString = "abbdef"; myString[2] = 'c' 。 诸如修剪,切片之类的字符串操作方法会返回新的字符串。 同样,如果您对同一个字符串有两个引用,则修改一个不会影响另一个 let a = b = "hello"; a = a + " world"; // b is not affected 但是,我一直都听到Ash在他的回答中提到的内容(使用Array.join进行连接的速度更快),因此我想测试一下连接字符串并将最快的方法抽象为StringBuilder的不同方法。 我写了一些测试来看看这是否正确(不是!)。 我一直认为这是最快的方法,尽管我一直认为添加方法调用可能会使它变慢。 function StringBuilder() { this._array = []; this._index = 0; } StringBuilder.prototype.append = function (str) { this._array
  • 为什么不变性在JavaScript中如此重要(或需要)?(Why is immutability so important (or needed) in JavaScript?)
    问题 我目前正在研究React JS和React Native框架。 在阅读关于Facebook的Flux和Redux实现的文章时,我遇到了Immutability或Immutable-JS库。 问题是,为什么不变性如此重要? 突变对象有什么问题? 它不是使事情变得简单吗? 举个例子,让我们考虑一个简单的新闻阅读器应用程序,其打开屏幕是新闻标题的列表视图。 如果我设置说一个带有初始值的对象数组,我将无法对其进行操作。 这就是不变性原则的意思,对不对? (如果我错了,请纠正我。)但是,如果我有一个必须更新的新News对象,该怎么办? 在通常情况下,我可以将对象添加到数组中。 在这种情况下,我该如何实现? 删除商店并重新创建? 是不是将对象添加到数组中的开销较小? 回答1 我最近一直在研究相同的主题。 我会尽力回答您的问题,并尝试分享到目前为止我学到的知识。 问题是,为什么不变性如此重要? 突变对象有什么问题? 它不是使事情变得简单吗? 基本上,可以归结为不变性(间接地)提高了可预测性,性能和允许进行突变跟踪的事实。 可预测性 突变会隐藏变化,从而产生(意外的)副作用,这可能会导致令人讨厌的错误。 强制执行不变性时,可以使应用程序体系结构和思维模型保持简单,这使对应用程序的推理变得更容易。 表现 即使向不可变对象添加值意味着需要在需要复制现有值的情况下创建新实例
  • 不变类的例子(Examples of immutable classes)
    问题 我已经知道不可变类的定义,但是我需要一些示例。 回答1 标准API中一些著名的不可变类: java.lang.String(已经提到) 基本类型的包装器类:java.lang.Integer,java.lang.Byte,java.lang.Character,java.lang.Short,java.lang.Boolean,java.lang.Long,java.lang.Double, java.lang.Float java.lang.StackTraceElement(用于构建异常stacktraces) 大多数枚举类是不可变的,但实际上这取决于具体情况。 (不要实现可变的枚举,这会在某种程度上使您搞砸。)我认为,至少标准API中的所有枚举类实际上都是不可变的。 java.math.BigInteger和java.math.BigDecimal(至少这些类本身的对象,子类可能会引入可变性,尽管这不是一个好主意) java.io.File。 请注意,这表示VM外部的对象(本地系统上的文件),该对象可能存在也可能不存在,并且具有一些方法可以修改和查询此外部对象的状态。 但是File对象本身保持不变。 (java.io中的所有其他类都是可变的。) java.awt.Font-表示用于在屏幕上绘制文本的字体(可能有一些可变的子类,但这肯定没有用) java.awt
  • 了解Javascript不可变变量(Understanding Javascript immutable variable)
    问题 我试图了解Javascript不可变变量的含义。 如果可以的话: var x = "astring"; x = "str"; console.log(x); //logs str` , then why it is immutable? 我唯一能想到的答案(从CI的一点点知道)是var x是指向值为“ astring”的内存块的指针,在第二条语句之后,它指向值为“ str”的另一个块。 是这样吗 还有一个额外的问题:我对Javascript的值类型感到困惑。 所有变量都是对象吗? 偶数和字符串? 回答1 值是不可变的; 变量不是; 他们拥有对其(原始)值的引用。 三种原始类型string,number和boolean具有对应的类型,其实例是object: String,Number和Boolean 。 它们有时称为包装器类型。 以下是原始值: 字符串:“ hello” 数字:6、3.14(JavaScript中的所有数字均为浮点数) 布尔值:true,false null:通常显式分配未定义:通常为默认值(自动分配) 所有其他值都是对象,包括基元的包装。 所以: 默认情况下对象是可变的对象具有唯一标识,并通过引用进行比较变量保存对对象的引用基元是不可变的比较基元的价值,他们没有个人身份 您可能会发现JavaScript原语的秘密生活是一个很好的解释。 同样,在ES6中
  • Scala 2.8和Scala 2.7之间的最大区别是什么?(What are the biggest differences between Scala 2.8 and Scala 2.7?)
    问题 我已经在Scala 2.7.5中编写了一个相当大的程序,现在我期待的是2.8版。 但是我很好奇Scala的发展中的这一巨大飞跃将如何影响我。 这两个Scala版本之间的最大区别是什么? 也许最重要的是: 我需要重写任何内容吗? 我是否要重写任何内容以仅利用一些很酷的新功能? 一般而言,Scala 2.8的新功能到底是什么? 回答1 您可以在此处找到Scala2.8中的新功能的预览(2009年4月),并附带了本文的最新内容(2009年6月) 命名和默认参数嵌套注释包对象 @专门改进的馆藏(这里可能需要重写) REPL将具有命令完成功能(更多有关此功能和本文中的其他技巧) 新的控制抽象(继续或中断) 增强功能(Swing包装器,表演等) “重写代码”不是强制性的(使用某些改进的Collections除外),而是某些功能,例如延续(Wikipedia:控制状态的抽象表示,或“其余计算”或“待执行的其余代码” ”)可以给您一些新的想法。 在这里可以找到很好的介绍,由Daniel撰写(Daniel也已在此主题中发布了更为详细和具体的答案)。 注意:Netbeans上的Scala似乎可以在2.8夜间版本上运行(与2.7.x的官方页面相比) 回答2 飞跃 迁移时,编译器可以为您提供一些安全网。 使用-deprecation针对2.7.7编译您的旧代码,并遵循所有弃用警告中的建议。
  • 如何在Swift中创建不可变数组?(How do you create an immutable array in Swift?)
    问题 如何在Swift中创建不可变数组? 简要阅读文档会建议您可以做 let myArray = [1,2,3] 但是可悲的是,这实际上产生了一个可变的,固定大小的数组。 这种可变性通常会产生令人困惑的别名,它们会产生意想不到的别名,并且会改变其参数: let outterArray = [myArray, myArray] outterArray[0][0] = 2000 outterArray //=> [[2000,2,3],[2000,2,3]] surprise! func notReallyPure(arr:Int[]) -> () { arr[0] = 3000 } notReallyPure(myArray) myArray // => [3000,2,3] 没有比C好多少了。 如果我想要不变性,那么将它包裹在NSArray的最佳选择就是这样: let immutableArray = NSArray(myArray: [1,2,3]) 好像疯了。 我在这里想念什么? 更新(2015-07-26): 这个问题可以追溯到Swift的早期。 从那以后,对Swift进行了更新,以使不可变数组实际上是不可变的,如下面的答案所示。 回答1 Xcode 6 beta 3改变了这种情况。正如您所描述的,过去数组是半可变的,它们的元素是可变的,但是长度是固定的
  • Kotlin和不可变集合?(Kotlin and Immutable Collections?)
    问题 我正在学习Kotlin,并且看起来我可能希望在明年使用它作为我的主要语言。 但是,关于Kotlin是否具有不可变集合的研究一直在引起争议,我试图弄清楚是否需要使用Google Guava。 有人可以给我一些指导吗? 默认情况下是否使用不可变集合? 哪些运算符返回可变或不可变的集合? 如果没有,是否有实施这些计划的计划? 回答1 标准库中的Kotlin列表是只读的: interface List<out E> : Collection<E> (source) 元素的一般有序集合。 该接口中的方法仅支持对列表的只读访问;请参见图11。 通过MutableList接口支持读/写访问。 参数 E-列表中包含的元素的类型。 如前所述,还有MutableList interface MutableList<E> : List<E>, MutableCollection<E> (source) 元素的通用有序集合,支持添加和删除元素。 参数 E-列表中包含的元素的类型。 因此,Kotlin通过其接口强制执行只读行为,而不是像默认Java实现那样在运行时抛出异常。 同样,有一个MutableCollection , MutableIterable , MutableIterator , MutableListIterator , MutableMap和MutableSet
  • JavaScript内存限制(JavaScript memory limit)
    问题 JavaScript应用程序可以存储的最大数据量是多少? 我猜这是由浏览器处理的,每个浏览器都有其局限性吗? 如果没有限制,将创建页面文件吗? 如果是这样,那不安全吗? 回答1 AFAIK,没有上限,您的脚本基本上可以使用内存,直到系统内存不足(包括交换)。 没有上限并不意味着您必须全部吃掉,用户可能不喜欢它。 回答2 在Chrome和Chromium操作系统中,内存限制是由浏览器定义的,您可以在开发人员工具的命令行中按以下命令来检查内存限制,方法是按F12键: > window.performance.memory.jsHeapSizeLimit 1090519040 在我的Windows 10操作系统上,它约为1 GB。 在Chrom(e / ium)上,您可以通过分配本机数组来避免堆大小限制: var target = [] while (true) { target.push(new Uint8Array(1024 * 1024)); // 1Meg native arrays } 这会使选项卡崩溃,速度约为2GB。 之后,Chrom(e / ium)陷入困境,并且不重新启动浏览器就无法重复测试。 我还建议您在深入了解杂草以尝试诊断或测量浏览器中与之相关的任何内存之前,先阅读TrackJS的有关监视JavaScript内存的博客文章。 您也可以在comp.lang
  • Swift中的不可变/可变集合(Immutable/Mutable Collections in Swift)
    问题 我指的是Apple的Swift编程指南,用于理解以Swift语言创建可变/不可变对象(数组,字典,集合,数据)。 但是我不明白如何在Swift中创建一个不可变的集合。 我想在Objective-C中看到以下Swift中的等效项 不变数组 NSArray *imArray = [[NSArray alloc]initWithObjects:@"First",@"Second",@"Third",nil]; 可变数组 NSMutableArray *mArray = [[NSMutableArray alloc]initWithObjects:@"First",@"Second",@"Third",nil]; [mArray addObject:@"Fourth"]; 不变字典 NSDictionary *imDictionary = [[NSDictionary alloc] initWithObjectsAndKeys:@"Value1", @"Key1", @"Value2", @"Key2", nil]; 可变字典 NSMutableDictionary *mDictionary = [[NSMutableDictionary alloc]initWithObjectsAndKeys:@"Value1", @"Key1", @"Value2", @"Key2", nil]
  • 如何识别Java中的不可变对象(How do I identify immutable objects in Java)
    问题 在我的代码中,我正在创建一个对象集合,各个线程将以一种仅在对象是不可变的情况下才安全的方式访问这些对象。 当试图将一个新对象插入到我的集合中时,我想测试一下它是否是不可变的(如果不是不变的,我将抛出一个异常)。 我可以做的一件事是检查一些众所周知的不可变类型: private static final Set<Class> knownImmutables = new HashSet<Class>(Arrays.asList( String.class, Byte.class, Short.class, Integer.class, Long.class, Float.class, Double.class, Boolean.class, BigInteger.class, BigDecimal.class )); ... public static boolean isImmutable(Object o) { return knownImmutables.contains(o.getClass()); } 这实际上使我省了90%的路,但是有时我的用户会想要创建自己的简单不可变类型: public class ImmutableRectangle { private final int width; private final int height; public
  • 一行初始化ArrayList(Initialization of an ArrayList in one line)
    问题 我想创建用于测试目的的选项列表。 首先,我这样做: ArrayList<String> places = new ArrayList<String>(); places.add("Buenos Aires"); places.add("Córdoba"); places.add("La Plata"); 然后,我将代码重构如下: ArrayList<String> places = new ArrayList<String>( Arrays.asList("Buenos Aires", "Córdoba", "La Plata")); 有一个更好的方法吗? 回答1 实际上,初始化ArrayList的“最佳”方法可能是您编写的方法,因为它不需要以任何方式创建新的List : ArrayList<String> list = new ArrayList<String>(); list.add("A"); list.add("B"); list.add("C"); 问题是引用该list实例需要大量输入。 还有其他选择,例如使用实例初始化程序(也称为“双括号初始化”)创建匿名内部类: ArrayList<String> list = new ArrayList<String>() {{ add("A"); add("B"); add("C"); }}; 但是,我不太喜欢这种方法
  • 有效实现不可变(双)LinkedList(Efficient implementation of immutable (double) LinkedList)
    问题 看过这个问题不可变还是不可变? 在阅读了我以前关于不变性的问题的答案后,我仍然对有效实现不变的简单LinkedList感到有些困惑。 就数组而言,这似乎很容易-复制数组并基于该副本返回新结构。 假设我们有一个通用的Node类: class Node{ private Object value; private Node next; } 并且基于上述类的LinkedList允许用户添加,删除等。现在,我们如何确保不可变性? 插入元素时,是否应该将所有引用递归复制到列表中? 我也对不可变或不可变的答案感到好奇吗? 提到了通过二叉树优化的cerain优化,从而导致log(n)的时间和空间。 另外,我在某处读到,在前面加上一个elem也是0(1)。 这让我很困惑,好像我们没有提供引用的副本一样,那么实际上我们在两个不同的源中修改了相同的数据结构,这打破了不变性。 您的答案是否还会在双向链表上起作用? 我期待对任何其他问题/解决方案的任何答复/指针。 在此先感谢您的帮助。 回答1 假设我们有一个基于上述的Node类和LinkedList类,允许用户添加,删除等。现在,我们如何确保不可变性? 通过将对象的每个字段都设为只读,并确保由这些只读字段之一引用的每个对象也是不可变的对象,可以确保不变性。 如果这些字段都是只读的,并且仅引用其他不可变数据,那么显然该对象将是不可变的! 插入元素时
  • 可变对象与不可变对象(Mutable vs immutable objects)
    问题 我试图让我了解可变对象和不可变对象。 使用可变对象会带来很多负面影响(例如,从方法中返回字符串数组),但是我很难理解它的负面影响。 使用可变对象的最佳实践是什么? 您是否应该尽可能避免使用它们? 回答1 好吧,这有几个方面。 没有参考身份的可变对象可能会在奇数时间导致错误。 例如,考虑使用基于值的equals方法的Person Bean: Map<Person, String> map = ... Person p = new Person(); map.put(p, "Hey, there!"); p.setName("Daniel"); map.get(p); // => null 当Person实例用作键时,它在映射中“丢失”,因为它的hashCode和相等性基于可变值。 这些值在映射表外部更改,并且所有散列都已过时。 理论家喜欢在这一点上竖琴,但是在实践中,我还没有发现这是一个太大的问题。 另一个方面是代码的逻辑“合理性”。 这是一个很难定义的术语,涵盖了从可读性到流程的所有内容。 通常,您应该能够查看一段代码并轻松了解其功能。 但是比这更重要的是,您应该能够使自己相信它可以正确地完成工作。 当对象可以在不同的代码“域”中独立更改时,有时会变得难以掌握位置和原因(“诡异的动作”)。 这是一个更难以举例说明的概念,但是在更大,更复杂的体系结构中经常会遇到这个问题。 最后
  • 字符串不可变有什么优势?(What's the advantage of a String being Immutable?)
    问题 有一次我研究了由于提高内存性能的原因而使字符串不可变的优点。 有人可以向我解释吗? 我无法在互联网上找到它。 回答1 不可变性(对于字符串或其他类型)可以具有许多优点: 由于您可以对原本无法创建的变量和参数进行假设,因此可以更轻松地对代码进行推理。 它简化了多线程编程,因为从无法更改的类型读取始终可以安全地并发执行。 通过允许将相同的值组合在一起并从多个位置引用,可以减少内存使用。 Java和C#都执行字符串实习,以减少嵌入在代码中的文字字符串的存储成本。 因为先前计算的状态可以在以后重用,所以它简化了某些算法(例如采用回溯或值空间分区的算法)的设计和实现。 不变性是许多功能编程语言中的基本原理-它允许将代码视为从一种表示形式到另一种表示形式的一系列转换,而不是一系列的突变。 不可变的字符串还有助于避免将字符串用作缓冲区的诱惑。 C / C ++程序中的许多缺陷与缓冲区溢出问题有关,这些问题是由于使用裸字符数组来编写或修改字符串值而导致的。 将字符串视为可变类型会鼓励使用更适合缓冲区操作的类型(请参见.NET或Java中的StringBuilder )。 回答2 考虑替代方案。 Java没有const限定词。 如果String对象是可变的,则将引用传递给字符串的任何方法都可能具有修改字符串的副作用。 不变的字符串消除了防御性复制的需要,并降低了程序错误的风险。 回答3
  • 为什么要在不可变类内的吸气剂中制作防御性副本?(Why make defensive copies in getters inside immutable classes?)
    问题 这个问题是关于良好的编程习惯和避免潜在的漏洞。 我读了约书亚·布洛赫(Joshua Bloch)的《有效的Java》,这就是我所想的: 为什么我应该考虑在不可变类的不可变类中使用getter方法创建防御性副本? 第二:为什么除了私有之外,我的领域也要最终确定? 这仅与性能有关(与安全无关)吗? 回答1 我相信这种情况可以证明以下说法是正确的: public class Immutable { private final String name; private Date dateOfBirth; public Immutable(String name, Date dateOfBirth) { this.name = name; this.dateOfBirth = dateOfBirth; } public String getName() { return name; } public Date getDateOfBirth() { return dateOfBirth; } } getName()很好,因为它也返回不可变的对象。 但是,由于客户端代码可以修改返回的对象,因此getDateOfBirth()方法可以破坏不可变性,因此也可以修改Immutable对象: Immutable imm = new Immutable("John", new Date())
  • JSONB字段中的对象的Postgresql查询数组(Postgresql query array of objects in JSONB field)
    问题 我在PostgreSQL 9.4数据库中有一个表,表中有一个称为接收器的jsonb字段。 一些示例行: [{"id": "145119603", "name": "145119603", "type": 2}] [{"id": "1884595530", "name": "1884595530", "type": 1}] [{"id": "363058213", "name": "363058213", "type": 1}] [{"id": "1427965764", "name": "1427965764", "type": 1}] [{"id": "193623800", "name": "193623800", "type": 0}, {"id": "419955814", "name": "419955814", "type": 0}] [{"id": "624635532", "name": "624635532", "type": 0}, {"id": "1884595530", "name": "1884595530", "type": 1}] [{"id": "791712670", "name": "791712670", "type": 0}] [{"id": "895207852", "name": "895207852", "type": 0}] [
  • copy和mutableCopy如何应用于NSArray和NSMutableArray?(How do copy and mutableCopy apply to NSArray and NSMutableArray?)
    问题 在NSArray或NSMutableArray上使用copy和mutableCopy什么区别? 这是我的理解; 这是正确的吗? // ** NSArray ** NSArray *myArray_imu = [NSArray arrayWithObjects:@"abc", @"def", nil]; // No copy, increments retain count, result is immutable NSArray *myArray_imuCopy = [myArray_imu copy]; // Copys object, result is mutable NSArray *myArray_imuMuta = [myArray_imu mutableCopy]; // Both must be released later // ** NSMutableArray ** NSMutableArray *myArray_mut = [NSMutableArray arrayWithObjects:@"A", @"B", nil]; // Copys object, result is immutable NSMutableArray *myArray_mutCopy = [myArray_mut copy]; // Copys object, result
  • Scala 2.8集合设计教程(Scala 2.8 collections design tutorial)
    问题 已锁定。 该问题及其答案被锁定,因为该问题是题外话,但具有历史意义。 它目前不接受新的答案或互动。 在我喘不过气来的混乱之后,有什么好的资源可以解释新的Scala 2.8集合库的结构。 我想找到一些有关以下内容如何组合在一起的信息: 集合类/特征本身(例如List , Iterable ) 为什么存在Like类(例如TraversableLike ) 伴随方法有什么作用(例如List.companion ) 我如何知道给定点范围内的implicit对象 回答1 前言 马丁·奥德斯基(Martin Odersky)的2.8系列演练可能是您的第一本参考书。 它也得到了建筑笔记的补充,这对那些想要设计自己的收藏的人们特别感兴趣。 在存在任何此类问题之前(实际上,在2.8.0本身发布之前)就以其他方式编写了此答案的其余部分。 您可以找到有关此文档的文档,其名称为Scala SID#3。 对Scala 2.7和2.8之间的差异感兴趣的人们也应该关注该领域的其他论文。 我将选择性地引用本文的内容,并补充我的一些想法。 马蒂亚斯(Matthias)在decodified.com上还生成了一些图像,可以在此处找到原始SVG文件。 收集类/特征本身 集合的特征实际上有三个层次:一个是可变集合,一个是不可变集合,一个没有对集合进行任何假设。 Scala 2.9中引入了并行
  • 如何创建一个不可变的类?(How do I create an immutable Class?)
    问题 我正在创建一个不可变的类。 我已将所有属性标记为只读。 我在班上有一个项目清单。 尽管如果该属性为只读,则可以修改列表。 公开列表的IEnumerable使其不可变。 我想知道使一个类不可变必须遵循的基本规则是什么? 回答1 我认为您在正确的轨道上- 注入类的所有信息都应在构造函数中提供所有属性只能是吸气剂如果将集合(或数组)传递给构造函数,则应将其复制以防止调用方稍后对其进行修改如果您要返回集合,请返回副本或只读版本(例如,使用ArrayList.ReadOnly或类似的版本),可以将其与上一点结合使用,并存储只读副本,以便在出现以下情况时返回调用者访问它),返回一个枚举数或使用其他允许对集合进行只读访问的方法/属性请记住,如果任何成员都是可变的,那么您可能仍然会出现可变类的外观-如果是这种情况,则应复制要保留的任何状态,并避免返回整个可变对象,除非您复制它们在将它们返回给调用者之前-另一个选择是仅返回可变对象的不变“部分”-感谢@Brian Rasmussen鼓励我扩展这一点 回答2 为了不可变,您的所有属性和字段都应为只读。 并且任何列表中的项目本身都应该是不可变的。 您可以如下创建一个只读列表属性: public class MyClass { public MyClass(..., IList<MyType> items) { ... _myReadOnlyList