【问题标题】:Return multiple values from function从函数返回多个值
【发布时间】:2025-12-04 14:50:01
【问题描述】:

有没有办法像在 Go(或其他一些语言)中那样在函数返回语句中返回多个值(除了返回一个对象)?

例如,在 Go 中我们可以这样做:

func vals() (int, int) {
    return 3, 7
}

这可以在 Dart 中完成吗?像这样的:

int, String foo() {
    return 42, "foobar";
} 

【问题讨论】:

标签: function return dart


【解决方案1】:

您可以使用Set<Object> 来返回多个值,

Set<object> foo() {
     return {'my string',0}
}

print(foo().first) //prints 'my string'

print(foo().last) //prints 0

【讨论】:

    【解决方案2】:

    你可以创建一个类来返回多个值 乙:

    class NewClass {
      final int number;
      final String text;
    
      NewClass(this.number, this.text);
    }
    

    生成值的函数:

     NewClass buildValues() {
            return NewClass(42, 'foobar');
          }
    

    打印:

    void printValues() {
        print('${this.buildValues().number} ${this.buildValues().text}');
        // 42 foobar
      }
    

    【讨论】:

      【解决方案3】:

      在 Dart 中的这种情况下,一个简单的解决方案可以返回一个列表,然后根据您的要求访问返回的列表。您可以通过索引访问特定值,也可以通过简单的 for 循环访问整个列表。

      List func() {
        return [false, 30, "Ashraful"];
      }
      
      void main() {
        final list = func();
        
        // to access specific list item
        var item = list[2];
        
        // to check runtime type
        print(item.runtimeType);
        
        // to access the whole list
        for(int i=0; i<list.length; i++) {
          print(list[i]);
        }
      }
      

      【讨论】:

        【解决方案4】:

        创建一个类:

        import 'dart:core';
        
        class Tuple<T1, T2> {
          final T1 item1;
          final T2 item2;
        
          Tuple({
            this.item1,
            this.item2,
          });
        
          factory Tuple.fromJson(Map<String, dynamic> json) {
            return Tuple(
              item1: json['item1'],
              item2: json['item2'],
            );
          }
        }
        

        随心所欲地调用它!

        Tuple<double, double>(i1, i2);
        or
        Tuple<double, double>.fromJson(jsonData);
        

        【讨论】:

          【解决方案5】:

          Dart 不支持多个返回值。

          你可以返回一个数组,

          List foo() {
            return [42, "foobar"];
          }
          

          或者,如果您希望输入值,请使用 Tuple 类,例如 https://pub.dartlang.org/packages/tuple 提供的包。

          另请参阅either,了解返回值或错误的方法。

          【讨论】:

          • +1 for tuple 与 Go 内置的功能最接近。它只是没有内置到 Dart 中,可能还没有太多需要,它们使语言尽可能简洁。
          • 还有其他优先事项。像这样的功能被讨论了好几次。目前它是关于具有强模式和通用功能的 Dart 2.0,并为 2.0 之后的更快迭代做了大量准备(统一前端,内核)。接下来希望不可为空的类型和其他类型。我不想添加太多功能,但我完全相信 Dart 团队会做出正确的决定。
          • either 是 dart 2.0 INCOMPATIBLE
          • 将返回类型改为List&lt;dynamic&gt;List&lt;Object&gt;
          • @zypro 对于 Dart 2.0 兼容的Either 实现,请参阅dartz
          【解决方案6】:

          我想补充一点,Go 中多个返回值的主要用例之一是错误处理,Dart 以自己的方式处理异常和失败的承诺。

          当然,这留下了一些其他用例,所以让我们看看使用显式元组时代码的外观:

          import 'package:tuple/tuple.dart';
          
          Tuple2<int, String> demo() {
            return new Tuple2(42, "life is good");
          }
          
          void main() {
            final result = demo();
            if (result.item1 > 20) {
              print(result.item2);
            }
          }
          

          不是那么简洁,但它是干净且富有表现力的代码。我最喜欢它的是,一旦您的快速实验项目真正启动并且您开始添加功能并且需要添加更多结构以保持领先地位,它就不需要太多改变。

          class FormatResult {
            bool changed;
            String result;
            FormatResult(this.changed, this.result);
          }
          
          FormatResult powerFormatter(String text) {
            bool changed = false;
            String result = text;
            // secret implementation magic
            // ...
            return new FormatResult(changed, result);
          }
          
          void main() {
            String draftCode = "print('Hello World.');";
            final reformatted = powerFormatter(draftCode);
            if (reformatted.changed) {
              // some expensive operation involving servers in the cloud.
            }
          }
          

          所以,是的,它对 Java 的改进并不大,但它可以工作,它很清晰,并且对于构建 UI 来说相当有效。而且我真的很喜欢我可以快速将东西组合在一起(有时在工作休息时开始使用 DartPad),然后在我知道项目将继续存在并发展时添加结构。

          【讨论】:

          • 该用例的函数式编程的一个常见模式是pub.dartlang.org/packages/either
          • +1 不重复发明*,让我们使用一个包,因为接下来有人想要一个 3 元素元组,然后是 Tuple3,等等......