Почему кто-то действительно должен использовать сеттер, когда обычная переменная может выполнить эту работу?

#dart

#dart

Вопрос:

Допустим, у вас есть сеттер-сеттер, подобный этому:

 int _foo;
set foo(int f) => _foo = f;
int get foo => _foo;
 

Но то же самое можно сделать, используя обычную

 int foo;
 

Я не понимаю, когда вам действительно понадобится сеттер? Может кто-нибудь, пожалуйста, объяснить, приведя пример?

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

1. Если обычная переменная действительно может выполнить эту работу, я думаю, это нормально. Сеттеры могут использоваться по-разному. Предположим, например, что ваша переменная — это не просто int , это особый вид целого числа с множеством дополнительных свойств. Было бы неплохо знать, что вы можете положиться на _foo, действительно обладающий этими свойствами. Если у вас есть установщик, вы можете установить пользовательскую логику, чтобы убедиться, что все происходит правильно.

2. Но я думаю, что мы не должны выполнять эту жесткую логическую обработку (как вы упомянули) в сеттере. Это просто не будет выглядеть хорошо. Сеттеры (на мой взгляд) не предназначены для таких случаев. Простая функция будет лучшим выбором.

3. Если вы позволяете людям делать blah.foo = что угодно, как вы собираетесь предотвратить попадание недопустимых целых чисел в переменную foo?

4. Устанавливаете ли вы какое-либо состояние из одного ввода через сеттер или через функцию, в основном зависит от предпочтений. Во многих языках, если вам нужно выполнить какую-либо логику, у вас нет выбора: вы должны использовать функцию. Dart дает вам выбор. Как вы хотите, чтобы выглядел ваш API? Вы хотите выполнить некоторую логику, которая кажется невидимой для вызывающих? Предпочитаю сеттер. Если логика сложна и требует много времени, функция может сделать это более очевидным для вызывающих.

5. @jamesdlin Это происходит с точки зрения разработчика Dart относительно того, почему они это сделали. Сэр, я прошу вас, пожалуйста, записать это как ответ, а не просто оставить его в качестве комментария.

Ответ №1:

Сеттер можно использовать, если у вас есть некоторая логика, которая должна выполняться при установке переменной. Базовым примером может быть следующий, где вы хотите отслеживать последнее обновление объекта:

 class A {
  int _foo = 42;
  DateTime _lastUpdated = DateTime.now();

  int get foo => _foo;
  set foo(int foo) {
    _foo = foo;
    _lastUpdated = DateTime.now();
  };

  DateTime get lastUpdated => _lastUpdated;
}
 

Другим вариантом использования было бы выполнить некоторую проверку, чтобы, например, выдать ошибку, если вы попытаетесь присвоить отрицательное целое число.