从函数返回多个值

有没有一种方法可以在函数返回语句中返回多个值(除了返回一个对象之外) ,就像我们在 Go (或其他语言)中所做的那样?

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

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

这能在达特做到吗? 类似这样的:

int, String foo() {
return 42, "foobar";
}
80490 次浏览

Dart doesn't support multiple return values.

You can return an array,

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

or if you want the values be typed use a Tuple class like the package https://pub.dartlang.org/packages/tuple provides.

See also either for a way to return a value or an error.

I'd like to add that one of the main use-cases for multiple return values in Go is error handling which Dart handle's in its own way with Exceptions and failed promises.

Of course this leaves a few other use-cases, so let's see how code looks when using explicit tuples:

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);
}
}

Not quite as concise, but it's clean and expressive code. What I like most about it is that it doesn't need to change much once your quick experimental project really takes off and you start adding features and need to add more structure to keep on top of things.

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.
}
}

So, yes, it's not much of an improvement over Java, but it works, it is clear, and reasonably efficient for building UIs. And I really like how I can quickly hack things together (sometimes starting on DartPad in a break at work) and then add structure later when I know that the project will live on and grow.

Create a class:

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'],
);
}
}

Call it however you want!

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

In this type of situation in Dart, an easy solution could return a list then accessing the returned list as per your requirement. You can access the specific value by the index or the whole list by a simple for loop.

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]);
}
}

You can create a class to return multiple values Ej:

class NewClass {
final int number;
final String text;


NewClass(this.number, this.text);
}

Function that generates the values:

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

Print:

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

you can use Set<Object> for returning multiple values,

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


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


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

The proper way to return multiple values would be to store those values in a class, whether your own custom class or a Tuple. However, defining a separate class for every function is very inconvenient, and using Tuples can be error-prone since the members won't have meaningful names.

Another (admittedly gross and not very Dart-istic) approach is try to mimic the output-parameter approach typically used by C and C++. For example:

class OutputParameter<T> {
T value;


OutputParameter(this.value);
}


void foo(
OutputParameter<int> intOut,
OutputParameter<String>? optionalStringOut,
) {
intOut.value = 42;
optionalStringOut?.value = 'foobar';
}


void main() {
var theInt = OutputParameter(0);
var theString = OutputParameter('');
foo(theInt, theString);
print(theInt.value); // Prints: 42
print(theString.value); // Prints: foobar
}

It certainly can be a bit inconvenient for callers to have to use variable.value everywhere, but in some cases it might be worth the trade-off.

you can use dartz package for Returning multiple data types

https://www.youtube.com/watch?v=8yMXUC4W1cc&t=110s

Dart is finalizing records, a fancier tuple essentially.
应该是在一个稳定的释放一个月的时间写作。
I'll try to update, it's already available with experiments flags.