← Назад к вопросам

В чем разница между var и string?

1.0 Junior🔥 161 комментариев
#Dart

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Разница между var и String

Вопрос о разнице между var и String в Dart касается объявления переменных и типизации. Это очень важная концепция для понимания типов данных в Dart.

Базовое объяснение

String — это конкретный тип данных, который хранит текст. var — это ключевое слово для автоматического определения типа переменной компилятором.

// String — явное объявление типа
String name = 'John';

// var — компилятор определит тип как String
var name2 = 'John';

// Результат одинаковый, но подход разный

Сравнение

АспектStringvar
ТипКонкретный типАвтоопределение типа
ЯвностьЯвное объявлениеНеявное (выводится компилятором)
КомпиляцияПроверяется тип StringКомпилятор определяет тип
БезопасностьВысокая (известен тип)Высокая (тип всё равно определяется)
ЧитаемостьЯвная и понятнаяЗависит от контекста
ПроизводительностьОдинаковаяОдинаковая

Пример 1: String

String name = 'Alice';           // явно String
String age = '25';               // явно String
String greeting = 'Hello, ' + name;  // явно String

print(name);     // Alice
print(name.length);  // 5
print(name.toUpperCase());  // ALICE

Пример 2: var

var name = 'Alice';              // компилятор понял, что это String
var age = '25';                  // компилятор понял, что это String
var greeting = 'Hello, ' + name; // компилятор понял, что это String

// На практике это точно то же самое
print(name);     // Alice
print(name.length);  // 5
print(name.toUpperCase());  // ALICE

Как работает var

Когда вы пишете var, компилятор анализирует правую часть выражения и определяет тип:

var x = 10;           // компилятор видит 10, определяет тип как int
var y = 10.5;         // компилятор видит 10.5, определяет тип как double
var z = 'Hello';      // компилятор видит строку, определяет тип как String
var list = [1, 2, 3]; // компилятор определяет тип как List<int>

Важно: var не значит динамический тип

в Dart есть специальный тип dynamic — это реально динамический тип:

// var — статический тип, определяется один раз
var name = 'John';
// name.length — OK
// name = 123;  — ОШИБКА! name уже String, можешь присвоить только String

// dynamic — реально динамический
dynamic name2 = 'John';
name2.length;   // OK
name2 = 123;    // OK! dynamic может быть любого типа
name2.length;   // ОШИБКА! int не имеет .length

Когда использовать String

String используй когда:

  1. Функция возвращает тип, и ты явно хочешь String
  2. Для документирования кода (явность)
  3. Когда важна читаемость для других разработчиков
// Явно и понятно
String getUserName() {
  return 'John';
}

class User {
  String name;        // явно поле String
  String email;       // явно поле String
  
  User(this.name, this.email);
}

final user = User('John', 'john@example.com');

Когда использовать var

var используй когда:

  1. Тип очевидный из контекста
  2. Для локальных переменных
  3. Когда это упрощает код
  4. При работе со сложными типами
// Тип очевидный
var name = 'John';           // явно String
var age = 30;                // явно int
var height = 180.5;          // явно double

// При работе со сложными типами var удобнее
var users = ['Alice', 'Bob', 'Charlie'];  // вместо List<String>
var userMap = {'name': 'John', 'age': 30};  // вместо Map<String, dynamic>
var iterator = names.iterator;  // вместо Iterator<String>

// Функции с очевидным типом возврата
var result = getUserName();  // если ясно, что возвращается String

Пример: объявления в Flutter приложении

class UserScreen extends StatefulWidget {
  @override
  State<UserScreen> createState() => _UserScreenState();  // var было бы неясно
}

class _UserScreenState extends State<UserScreen> {
  String userName = '';      // явное, поле класса — используем String
  var email = '';            // допустимо для локальной переменной
  final userId = 123;        // final int, можно var
  
  @override
  Widget build(BuildContext context) {
    var theme = Theme.of(context);     // OK, тип очевидный
    var size = MediaQuery.of(context).size;  // OK
    var textController = TextEditingController();  // OK
    
    return Scaffold(
      body: Column(
        children: [
          var child1 = Text(userName),  // ❌ ОШИБКА! var только для выражений, не для присваивания
          Text(userName),                // ✅ Правильно
        ],
      ),
    );
  }
}

Null safety: String? vs var?

// String? — явно, может быть null
String? name = null;
String? name2 = 'John';

// var? — компилятор определяет (может быть null или не null)
var name3 = null;  // компилятор видит null, тип становится Null
var name4 = 'John';  // компилятор видит строку, тип String (не nullable)

// Если нужно явно null-безопасно
var name5 = 'John' as String?;  // явно String?

Best Practice в Dart сообществе

Cообщество Dart рекомендует var для локальных переменных, если тип очевидный:

// ✅ Хорошие практики
var name = 'John';           // локальная переменная, тип очевидный
var users = <User>[];        // явно <User>
var result = _calculateSum();  // результат функции

// Но используй явный тип когда:
String getUserName() { ... }  // возвращаемый тип явно
class User {
  String name;  // поля класса явно
  String email;
}

Проверка типа в runtime

var value = 'Hello';

// Проверка типа
if (value is String) {
  print('Это String');
  print(value.length);  // 5
}

// Type casting
var anyValue = 'test';
if (anyValue is String) {
  String str = anyValue as String;  // явное приведение
}

Почему вообще нужна типизация?

// Без типизации (опасно)
var obj = getUser();  // что вернулось? User? String? int?
print(obj.name);      // ошибка! может не быть поля name

// С явной типизацией (безопасно)
User user = getUser();
print(user.name);     // OK, User точно имеет name

// С var, но очевидного типа (безопасно)
var user = User('John', 'john@example.com');  // компилятор знает, что это User
print(user.name);  // OK

Заключение

ИспользуйГдеПример
StringВозвращаемые типы, поля классаString getName() { ... }
varЛокальные переменные с очевидным типомvar name = 'John';
dynamicРедко, когда действительно нужна динамикаdynamic value = api.call();

Вывод: String — это тип данных для текста, var — это инструмент автоопределения типа. Обе работают одинаково быстро. Выбирай var для локальных переменных если тип очевидный, и явный тип (String, int, List) для публичного API и полей классов. Это делает код безопаснее и понятнее.

В чем разница между var и string? | PrepBro