咨询Dart List动态索引扩展实现方案:支持.数字索引语法
Dart List 动态索引扩展实现方案
首先明确:Dart语法不允许直接使用myList.1这种写法——因为成员访问的标识符(.后面的部分)必须符合Dart的标识符规则:必须以字母、下划线或$开头,后续可跟数字、字母、下划线或$,纯数字的标识符会直接触发语法错误,无法通过编译。
以下是两种最接近需求的可行实现方案:
方案1:带前缀的索引访问(模拟.数字风格)
通过包装类结合noSuchMethod实现,使用$数字作为合法标识符来模拟需求的写法:
实现代码
class IndexedList<T> { final List<T> _innerList; IndexedList(this._innerList); @override dynamic noSuchMethod(Invocation invocation) { // 仅处理getter调用 if (invocation.isGetter) { final symbolStr = invocation.memberName.toString(); // 匹配形如$0、$1的标识符 final match = RegExp(r"'(\$(\d+))'").firstMatch(symbolStr); if (match != null) { final index = int.parse(match.group(2)!); return _innerList[index]; } } throw NoSuchMethodError.withInvocation(this, invocation); } } // 给原生List添加扩展,快速转为IndexedList extension ListToIndexed<T> on List<T> { IndexedList<T> get idx => IndexedList(this); }
使用方式
final myList = ['one', 'two', 'three']; print(myList.idx.$1); // 输出: two print(myList.idx.$5); // 抛出RangeError(和原生List索引越界行为一致)
方案2:调用式索引访问
通过扩展给List添加call方法,用myList(数字)的写法替代,语法更简洁:
实现代码
extension ListIndexCall<T> on List<T> { T call(int index) => this[index]; }
使用方式
final myList = ['one', 'two', 'three']; print(myList(1)); // 输出: two print(myList(5)); // 抛出RangeError
补充说明
如果坚持想要最接近.数字的写法,也可以考虑使用下划线前缀(如._1),只需修改方案1中的正则表达式为r"'(_(\d+))'"即可,但可读性不如$数字方案。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

