Dart扩展函数未找到。

23

我有一个关于Flutter的项目,非常想在其中使用扩展方法。 我已经升级了pubspec.yaml文件,使用了sdk: ">=2.6.0 <3.0.0"。 我创建了一个名为list_extensions.dart的文件,其内容如下:

import 'dart:math';

extension ListExtension<T> on List<T> {

  T randomElement() => this.elementAt(Random().nextInt(this.length));

}

当我尝试在其他文件中使用这个扩展方法时,像这样

String getRandomText(List<String> texts) => texts.randomElement();

我看到一个编译器错误,错误信息为:方法“randomElement”在“List”类中未定义
但是当我尝试在list_extensions.dart文件中使用此扩展方法时,编译器没有报错。
问题在于我的另一个项目可以找到我声明的所有扩展方法。 flutter doctor显示:
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel master, v1.10.17-pre.74, on Mac OS X 10.15 19A603, locale en-RU)
[!] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
    ✗ Android license status unknown.
      Try re-installing or updating your Android SDK Manager.
      See https://developer.android.com/studio/#downloads or visit https://flutter.dev/setup/#android-setup for detailed instructions.
[✓] Xcode - develop for iOS and macOS (Xcode 10.2)
[✓] Android Studio (version 3.5)
[✓] Android Studio (version 3.4)
[✓] VS Code (version 1.39.2)
[✓] Connected device (1 available)

flutter --version的意思是:

Flutter 1.10.17-pre.74 • channel master • https://github.com/flutter/flutter.git
Framework • revision bcc93bca23 (6 days ago) • 2019-11-13 11:31:20 -0800
Engine • revision 31cd2dfca2
Tools • Dart 2.7.0

我该怎么做才能强制编译器看到我的扩展方法?


24
扩展名定义的文件必须被导入。 - Rémi Rousselet
如果我手动添加导入,我确实可以使用我声明的扩展方法。感谢您的建议。但是我认为IDE应该将扩展方法识别为我扩展的类的方法。我想使用自动完成。它至少在不久的将来会按照我的期望工作吗? - Ilia Kurtov
7
我从Android和Kotlin转到Flutter和Dart,发现在整个项目中随时都应该使用扩展方法,这对我来说非常实用。否则,我需要知道在应用程序的哪些类中声明了哪些扩展。静态函数可以被找到,但扩展方法却不能?这对我来说似乎是不合逻辑的。 - Ilia Kurtov
4
也许我没有清楚表达我的期望行为。我不想在没有导入的情况下使用扩展方法,我完全同意这是不合适的。我只希望IDE能够看到它们,并在我输入它们的名称时建议我导入它们 - 简单的自动完成与自动导入。 - Ilia Kurtov
12
我知道支持是新添加的,但我想在这个问题上提出我的看法。扩展函数比工具函数的一个巨大优势是它们会在自动完成中显示。如果我需要知道每个扩展函数在哪里,那么最好还是使用 Utils。实际上,使用带有建议和自动导入的工具类可能比记住并手动输入导入语句更容易。 - xip
显示剩余4条评论
5个回答

35

这不是你的情况,但对我来说,在更新了Android Studio、Flutter插件和Dart插件后,它起作用了。也许它可以帮助其他人。

支持扩展方法的版本:

  • Android Studio 3.6.2
  • Flutter插件 192.7761
  • Dart插件 45.1.1

另一个重要的点是扩展必须命名。如果没有命名,则不能在其他文件中使用:

私有扩展

extension on Banana {
  // ...
}

公共扩展:

extension BananaExtension on Banana {
  // ...
}

我在 Dart extension 的宣传评论中发现了这个东西,YouTube 上的视频


3
看起来这在3.6.3版本中出了问题 :( - Ajay Gautam
数字在 Dart 和 Flutter 中被交换了。 - spydon

2

扩展方法是在Dart 2.7中引入的,因此您可以更改您的sdk版本:">=2.7.0 <3.0.0"


是的,我从一开始就声明了它。但肯定它可以帮助到某些人。 - Ilia Kurtov

1
如果这对未来有所帮助,我遇到了一个问题,就是在使用扩展名时使用了final而不是类名。我的代码如下:
extension StringExtensions on String {
  bool isFuture() {
    ...
  }
}

final time = 'some time of day';
if (time.isFuture()) {
...
}

这个出现了错误,为了解决它,我需要做:

final String time = 'some time of day';

0
这是我的扩展,我在string_extension.dart中创建了这个扩展。
extension EmailValidator on String {
  bool isValidEmail() {
    return RegExp(
            r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$')
        .hasMatch(this);
  }
}

因此,为了使这个扩展工作,你只需要导入这个扩展文件,就像这样

import 'package:projectname/extensions/string_extension.dart';

然后

final String email = 'test@gmail.com';
if(email.isValidEmail()){
}


0

你需要在 pubspec.yaml 文件中更新 SDK 版本至 2.6

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接