Возвращает несколько значений из функции

#dart

Вопрос:

Есть ли способ вернуть несколько значений в операторе возврата функции (кроме возврата объекта), как это можно сделать в Go (или на некоторых других языках)?

Например, в Go мы можем сделать:

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

Можно ли это сделать в Dart? Что-то вроде этого:

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

Комментарии:

1. Я не знаю, действительно ли какие-либо языки возвращают несколько значений. Python, который использует тот же синтаксис, что и вы выше, возвращает кортеж, который представляет собой простой объект. Я подозреваю, что Go похож.

2. Подходящий: groups.google.com/a/dartlang.org/forum/m/#!topic/misc/…

3. Lua также может возвращать несколько значений.

Ответ №1:

Dart не поддерживает несколько возвращаемых значений.

Вы можете вернуть массив,

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

или, если вы хотите, чтобы значения вводились, используйте Tuple класс, подобный пакету https://pub.dartlang.org/packages/tuple обеспечивает.

См.Также either способ возврата значения или ошибки.

Комментарии:

1. 1 для tuple которого наиболее точно соответствует тому, что Go делает со своим встроенным. Он просто не встроен в Dart, по-видимому, пока не очень нужен, и они поддерживают язык как можно более легким.

2. Были и другие приоритеты. Подобные функции обсуждались несколько раз. В настоящее время речь идет о Dart 2.0 с сильным режимом и универсальными функциями, а также о большой подготовке к более быстрой итерации после 2.0 (унифицированный интерфейс, ядро). Далее, надеюсь,ненулевые типы и другие. Я предпочитаю не добавлять слишком много функций, но я полностью доверяю команде Dart в принятии правильных решений.

3. Также либо dart 2.0 НЕСОВМЕСТИМ .

4. Измените тип возврата на List<dynamic> или List<Object>

5. @zypro Для реализации, совместимой с Dart 2.0 Either , см. dartz

Ответ №2:

Я хотел бы добавить, что одним из основных вариантов использования нескольких возвращаемых значений в 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 resu<
  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, но это работает, это понятно, и достаточно эффективно для создания UIS. И мне действительно нравится, как я могу быстро соединять вещи (иногда начиная с DartPad в перерыве на работе), а затем добавлять структуру позже, когда я знаю, что проект будет жить и развиваться.

Комментарии:

1. Распространенным примером функционального программирования для этого случая использования является pub.dartlang.org/packages/either

2. 1 за то, что вы не изобретаете велосипед заново, давайте использовать пакет, потому что следующее, что кому-то нужен кортеж из 3 элементов, затем есть кортеж3 и так далее…

Ответ №3:

Создайте класс:

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

Ответ №4:

Вы можете создать класс для возврата нескольких значений Ej:

 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
  }
 

Ответ №5:

вы можете использовать Set<Object> для возврата нескольких значений,

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

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

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

Ответ №6:

В такой ситуации в 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]);
  }
}