[英]Dart - How to extend Map with a specific constructor?
我想用抽象的 class 擴展 Darts map 用於數據庫表,然后必須為每個表擴展(參見下面的完整示例)。 抽象 class 有一個構造函數,它已經設置了一些條目,但沒有顯式調用其超級 class 中的任何構造函數。
問題是創建子類並直接設置條目(如 map 允許)。
我試圖正確地遵循這個答案。
import 'package:uuid/uuid.dart';
void main(List<String> args) {
Map<String, dynamic> map = {
'key': 99,
};
SomeTable one = SomeTable();
print('$one with ${one.length} entries -> ${one.prettyPrint()}');
SomeTable another = SomeTable();
one['child'] = another;
print('$one with ${one.length} entries -> ${one.prettyPrint()}');
SomeTable third = {
'key': 17,
};
}
class SomeTable extends TableMap {
SomeTable() : super('sometable');
void someSpecificFunction() {}
}
abstract class TableMap implements Map<String, dynamic> {
final Map _inner = <String, dynamic>{};
static const String id = 'id', // 64bit
uuid = 'uuid',
identifier = 'identifier', // String "$tablename:$id"
tablename = 'tablename';
/// Constructor
TableMap(String _tablename) {
String uuidAsString = Uuid().v4();
_inner[uuid] = uuidAsString;
_inner[identifier] = tablename + ':' + uuidAsString;
_inner[tablename] = _tablename;
}
/// Returns `true` if `ìd` = `null`
bool get isNew => ([id] == null) ? true : false;
@override
operator [](Object key) {
return _inner[key];
}
@override
void operator []=(String key, value) {
_inner[key] = value;
}
@override
void addAll(Map<String, dynamic> other) {
_inner.addAll(other);
}
@override
void addEntries(Iterable<MapEntry<String, dynamic>> newEntries) {
_inner.addEntries(newEntries);
}
@override
Map<RK, RV> cast<RK, RV>() {
return _inner.cast<RK, RV>();
}
@override
void clear() {
_inner.clear();
}
@override
bool containsKey(Object key) {
return _inner.containsKey(key);
}
@override
bool containsValue(Object value) {
return _inner.containsValue(value);
}
@override
Iterable<MapEntry<String, dynamic>> get entries => _inner.entries;
@override
void forEach(void Function(String key, dynamic value) f) {
_inner.forEach(f);
}
@override
bool get isEmpty => _inner.isEmpty;
@override
bool get isNotEmpty => _inner.isNotEmpty;
@override
Iterable<String> get keys => _inner.keys;
@override
int get length => _inner.length;
@override
Map<K2, V2> map<K2, V2>(
MapEntry<K2, V2> Function(String key, dynamic value) f) {
return _inner.map(f);
}
@override
putIfAbsent(String key, Function() ifAbsent) {
return _inner.putIfAbsent(key, ifAbsent);
}
@override
remove(Object key) {
return _inner.remove(key);
}
@override
void removeWhere(bool Function(String key, dynamic value) predicate) {
_inner.removeWhere(predicate);
}
@override
update(String key, Function(dynamic value) update, {Function() ifAbsent}) {
return _inner.update(key, update, ifAbsent: ifAbsent);
}
@override
void updateAll(Function(String key, dynamic value) update) {
_inner.updateAll(update);
}
@override
Iterable get values => _inner.values;
/// Creates a string by putting each entry on a separate line and
/// prefixing it with spaces according to its depth within the map.
String prettyPrint() {
return _prettyPrintMap(this, 0);
}
static final String _spaces = ' ';
String _prettyPrintList(List<dynamic> list, int depth) {
depth++;
String _indent = _spaces.substring(0, 2 * depth);
String out = '[\n';
list.forEach((element) {
out = out + _indent;
print('_printList( element=$element is ${element.runtimeType}');
if (element is Map) {
out = out + _prettyPrintMap(element, depth) + ',\n';
} else if (element is List) {
out = out + _prettyPrintList(element, depth) + ',\n';
} else {
out = out + element.toString() + ',\n';
}
});
depth--;
return out + ']';
}
String _prettyPrintMap(Map<dynamic, dynamic> map, int depth) {
depth++;
String _indent = _spaces.substring(0, 2 * depth);
String out = '{\n';
map.forEach((k, v) {
out = out + _indent + k + ': ';
if (v is Map) {
out = out + _prettyPrintMap(v, depth) + ',\n';
} else if (v is List) {
out = out + _prettyPrintList(v, depth);
} else {
out = out + v.toString() + ',\n';
}
});
depth--;
return out + '}';
}
}
您的TableMap
class 沒有extend Map
,它implement
了它。 因此,您不要調用Map
的構造函數——這似乎是正確的方法。
如果你想在構造時填充你的數據保存Map _inner
,你可以在你的構造函數中這樣做; 你現在的做法看起來不錯,或者你可以在構造函數中完全初始化你的變量。
當然,您不能只為自定義實現使用文字語法 - 文字基本上綁定到默認的Map
。 但是您可以添加一個構造函數,該構造函數接受一些值並將這些值傳遞到您的私有基礎 class 構造函數中,然后將值添加到_inner
上。
例如,您可以添加(類似於Map
接口):
factory SomeTable.fromEntries(Iterable<MapEntry> entries) {
final table = SomeTable();
table._inner.addEntries(entries);
}
然后使用它:
SomeTable third = SomeTable.fromEntries({
'key': 17,
});
同樣,您可以將Map
或Iterable
添加到TableMap
class 的現有或新構造函數中,並在構造過程中傳遞數據。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.