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

使用dart_eval执行字符串Dart代码时无法继承外部类的问题

解决dart_eval中字符串代码继承外部类的问题

要让eval字符串里的Dog继承外部定义的Animal,核心是通过dart_eval的桥接机制把外部类暴露给eval运行时——因为dart_eval的沙箱环境无法直接识别普通的外部Dart类。具体操作步骤如下:

1. 为Animal类创建桥接定义

定义一个桥接类作为外部Animal和eval沙箱的中间层,告诉编译器Animal的结构信息:

class $Animal extends $Instance {
  $Animal(Object? value) : super(value);

  static final $type = BridgeTypeRef(CoreTypes.object);
  static final $declaration = BridgeClassDef(
    BridgeClassType($type, isAbstract: false),
    // 注册无参构造函数,匹配外部Animal的构造方式
    constructors: {
      '': BridgeConstructorDef(BridgeFunctionDef(returns: $type, params: []))
    },
    methods: {},
    getters: {},
    setters: {},
    fields: {},
  );

  @override
  $Value? getProperty(Runtime runtime, String identifier) {
    return super.getProperty(runtime, identifier);
  }

  @override
  void setProperty(Runtime runtime, String identifier, $Value value) {
    super.setProperty(runtime, identifier, value);
  }
}

2. 注册桥接类到编译器和运行时

编译前把桥接定义传给编译器,运行时再绑定桥接类到真实的Animal类型:

// 编译阶段:让编译器识别Animal的桥接定义
final compiler = Compiler();
compiler.defineBridgeClasses([$Animal.$declaration]);

// 运行阶段:绑定桥接类到真实的Animal构造函数
final runtime = Runtime.ofProgram(program)
  ..registerBridgeFunc('package:example/main.dart', 'Animal.', 
    (runtime, target, args) => $Animal(Animal()));

完整修改后的代码

import 'package:dart_eval/dart_eval.dart';
import 'package:dart_eval/dart_eval_bridge.dart';
import 'package:dart_eval/dart_eval_extensions.dart';
import 'package:dart_eval/stdlib/core.dart';

class Animal {}

class $Animal extends $Instance {
  $Animal(Object? value) : super(value);

  static final $type = BridgeTypeRef(CoreTypes.object);
  static final $declaration = BridgeClassDef(
    BridgeClassType($type, isAbstract: false),
    constructors: {
      '': BridgeConstructorDef(BridgeFunctionDef(returns: $type, params: []))
    },
    methods: {},
    getters: {},
    setters: {},
    fields: {},
  );

  @override
  $Value? getProperty(Runtime runtime, String identifier) {
    return super.getProperty(runtime, identifier);
  }

  @override
  void setProperty(Runtime runtime, String identifier, $Value value) {
    super.setProperty(runtime, identifier, value);
  }
}

void main(List<String> args) {
  final source = '''
    class Dog extends Animal {
    }
    Dog test() {
       final dog = Dog();
       return dog;
    }
    int sum(int a, int b) {
      return a + b;
    }

    int calculate() {
      test();
      return sum(1, 1);
    }
  ''';

  final compiler = Compiler();
  compiler.defineBridgeClasses([$Animal.$declaration]);

  final program = compiler.compile({'example': {'main.dart': source}});

  final runtime = Runtime.ofProgram(program)
    ..registerBridgeFunc('package:example/main.dart', 'Animal.', 
      (runtime, target, args) => $Animal(Animal()));

  final result = runtime.executeLib('package:example/main.dart', 'test', []);

  print(result);
}

关键原理说明

  • dart_eval的运行时是独立沙箱,外部类必须通过桥接机制才能被沙箱内代码访问、继承。
  • $Animal作为中间层,负责在外部Animal实例和eval沙箱的内部表示之间转换数据、传递调用。

内容的提问来源于stack exchange,提问作者ZhangWei-Bi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 13:50:33