2014-02-13 2 views

ответ

11

Использование clone() в Java является сложным и сомнительным 1,2. Эффективно clone() является копирующим конструктором, и для этого типы Dart List, Map и Set имеют named constructor с именем .from(), которые выполняют shallow copy; например учитывая эти заявления

Map<String, int> numMoons, moreMoons; 
    numMoons = const <String,int>{ 'Mars' : 2, 'Jupiter' : 27 }; 
    List<String> planets, morePlanets; 

вы можете использовать .from() так:

moreMoons = new Map<String,int>.from(numMoons) 
    ..addAll({'Saturn' : 53 }); 
    planets = new List<String>.from(numMoons.keys); 
    morePlanets = new List<String>.from(planets) 
    ..add('Pluto'); 

Обратите внимание, что List.from() более обычно принимает итератор, а не только List.

Для полноты я должен упомянуть, что класс dart:htmlNode определяет метод clone().


И. Блох, "Effective Java" 2-е изд., Пункт 11.
B. Venners, "Josh Bloch on Design: Copy Constructor versus Cloning", 2002. Ссылка отсюда . Цитата из статьи:

Если вы читали пункт о клонировании в моей книге, особенно если вы читаете между строками, вы будете знать, что я думаю, что клон глубоко сломан. --- J.Bloch

Dart Issue #6459, clone instance(object).

+4

Джош Блох фактически был вовлечен в некоторые из ранних проектов API коллекций Дартов. [Старое интервью] (https://www.youtube.com/watch?v=wmsVHdllIPM). –

+1

. Из-под() и .addAll() на самом деле не делается клонирование. Они добавляют ссылку в новый Map/List/Set. Например: Map map1 = { 'one': {'name': 1}, 'two': {'name': 2}, 'three': [{ 'a': { 'A' : 1, 'В': 2 }, 'B': { 'а': 3, 'В': 4} }] }; Map map2 = new Map.from (map1); map2 ['two'] ['name'] = 4; После изменения map2 ['two'] ['name'], map1 также изменен – kzhdev

+1

Вправо. '.from()' является конструктором _shallow_ copy. Чтобы быть ясным, я никогда не говорил, что '.from()' выполнил операцию клонирования. Я писал, что 'clone()' был своего рода конструктором копий. –