You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

咨询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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 08:28:24