Data Types & Operators
Every value in Dart has a type. The type decides what you can do with the value: you can divide numbers, make text uppercase and combine true/false conditions, but you cannot divide a name by two. Knowing the core types well saves you from many bugs, especially with money, marks and user input.
This lesson covers numbers, strings and booleans, the operators that work on them, and how to convert one type into another.
The core types
| Type | Holds | Example |
|---|---|---|
int | Whole numbers | 42, -7, 1_00_000 |
double | Numbers with a decimal point | 98.6, 0.5 |
num | Either an int or a double | num marks = 91; |
String | Text | 'Kochi', "Hindi: नमस्ते" |
bool | true or false | isPassed = true |
Object | Any non-null value | Object value = 3; |
dynamic | Any value, with type checks switched off | Avoid in new code |
Collections such as List and Map get their own lesson: Lists, Sets & Maps. Records, which group a few values together, are in Records & Patterns.
Every Dart value is an object, even numbers. That is why you can call methods on a number, such as 7.isOdd or 3.75.round().
Numbers and arithmetic
Four friends in Pune split a restaurant bill. This program shows all the arithmetic operators:
void main() {
const bill = 1450;
const friends = 4;
print(bill + 50); // addition
print(bill - 50); // subtraction
print(bill * 2); // multiplication
print(bill / friends); // division always gives a double
print(bill ~/ friends); // integer division
print(bill % friends); // remainder
var tip = 100;
tip += 20; // same as tip = tip + 20
tip++; // add 1
print(tip);
const population = 1_42_00_000; // digit separators (Dart 3.6+)
print(population);
}1500 1400 2900 362.5 362 2 121 14200000
Two operators surprise beginners. / always returns a double, even for 10 / 2 (which gives 5.0). ~/ divides and throws away the decimal part, so each friend pays 362 and the remainder operator % tells you 2 rupees are left over.
Underscores between digits, such as 1_42_00_000, are digit separators. They only make the number easier to read; Dart ignores them. You can group digits the Indian way (lakhs and crores) or any other way.
Converting between types
Text typed by a user is always a String, even if it looks like a number. Convert it before doing maths:
void main() {
final typedMarks = '87';
final marks = int.parse(typedMarks);
print(marks + 5);
final price = double.parse('499.5');
print(price.toStringAsFixed(2)); // always two decimals
print(int.tryParse('eighty')); // null instead of a crash
const average = 78.666;
print(average.round()); // nearest int
print(average.floor()); // round down
print(average.toInt()); // drop the decimals
final rollNo = 7;
print('Roll ${rollNo.toString().padLeft(3, '0')}');
print(10 / 2);
}92 499.50 null 79 78 78 Roll 007 5.0
int.parse throws an error for bad text, so use int.tryParse with ?? (see Variables & Sound Null Safety) for anything a user types. toStringAsFixed(2) is the simplest way to show money with exactly two decimals.
Strings
Strings can use single or double quotes. Dart style prefers single quotes. Strings cannot be changed in place; every method returns a new string.
void main() {
const station = ' New Delhi ';
final clean = station.trim();
print(clean.toUpperCase());
print(clean.length);
print(clean.contains('Delhi'));
print(clean.startsWith('New'));
print(clean.replaceAll(' ', '-'));
print(clean.substring(4)); // from index 4 to the end
print('Rohtak,Jaipur,Pune'.split(','));
const address = '''
House 12, Model Town
Rohtak 124001''';
print(address);
print(r'Raw string: $name and \n stay as typed');
print('Train ' 'number ' '12015'); // adjacent strings are joined
}NEW DELHI 9 true true New-Delhi Delhi [Rohtak, Jaipur, Pune] House 12, Model Town Rohtak 124001 Raw string: $name and \n stay as typed Train number 12015
Triple quotes (''' or """) make a multi-line string. A string with r in front is a raw string, where $ and \n are not special. String positions (indexes) start at 0, so substring(4) skips New and keeps Delhi.
Booleans, comparisons and logic
Comparison operators produce a bool. Logical operators combine them:
void main() {
const marks = 72;
const attendance = 68;
print(marks >= 40); // greater than or equal
print(marks == 100); // equal
print(marks != 100); // not equal
final canSitExam = attendance >= 75 || marks >= 70; // OR
final scholarship = marks >= 90 && attendance >= 90; // AND
print('Can sit exam: $canSitExam');
print('Scholarship: $scholarship');
print('No scholarship: ${!scholarship}'); // NOT
final result = marks >= 40 ? 'Pass' : 'Fail'; // conditional expression
print(result);
}true false true Can sit exam: true Scholarship: false No scholarship: true Pass
&& is true only if both sides are true. || is true if at least one side is true. Dart stops early: in a || b, if a is true, b is never evaluated. The conditional expression condition ? valueIfTrue : valueIfFalse picks one of two values, and you will use it constantly in Flutter to choose between two widgets.
Type tests: is, is! and as
Sometimes a value has a general type such as Object, and you need to know what it really is:
void describe(Object value) {
if (value is int) {
print('A whole number, doubled: ${value * 2}');
} else if (value is String) {
print('Text with ${value.length} characters');
} else {
print('Something else: $value');
}
}
void main() {
describe(21);
describe('Meera');
describe(true);
Object score = 88.5;
print(score is! int);
final asDouble = score as double;
print(asDouble + 1.5);
}A whole number, doubled: 42 Text with 5 characters Something else: true true 90.0
After value is int succeeds, Dart promotes value to int inside that block, just like the null checks you saw before. as forces a type and throws an error if it is wrong, so prefer is checks. Avoid dynamic: with dynamic, the compiler stops checking, and mistakes such as calling a method that does not exist appear only when the app runs.
Common mistakes
- Expecting
/to give anint.7 / 2is3.5. Use~/for whole-number division. - Adding a string and a number.
'Total: ' + 50is an error. Use interpolation:'Total: $total'. - Using
int.parseon user input. It crashes on bad text; useint.tryParse. - Storing money in
doublefor calculations. Store paise in anintinstead.
Key points
- Core types:
int,double,num,String,bool; everything is an object. /returns adouble;~/gives integer division and%the remainder.- Convert with
int.parse,int.tryParse,double.parse,toString()andtoStringAsFixed(). - Strings are immutable; methods like
trim,splitandreplaceAllreturn new strings. &&,||,!andcondition ? a : bwork withboolvalues.ischecks a type and promotes the variable;asforces a type and can throw.
Exercise
A canteen in Jaipur sells samosas at ₹15 each. Store the typed quantity '23' as a string, convert it, and print the total. The canteen packs samosas in boxes of 6: print how many full boxes there are and how many samosas are left over. Finally, print 'Bulk order' if the quantity is 20 or more, otherwise 'Regular order', using a conditional expression.
Show solution
void main() {
const pricePerSamosa = 15;
const boxSize = 6;
final quantity = int.tryParse('23') ?? 0;
print('Total: ₹${quantity * pricePerSamosa}');
print('Full boxes: ${quantity ~/ boxSize}');
print('Loose samosas: ${quantity % boxSize}');
print(quantity >= 20 ? 'Bulk order' : 'Regular order');
}Total: ₹345 Full boxes: 3 Loose samosas: 5 Bulk order
~/ counts complete boxes and % gives what is left after filling them. int.tryParse with ?? 0 keeps the program safe if the text is not a number.
Quick Quiz
1. What does 17 ~/ 5 give?
~/ is integer division: it drops the decimal part.
2. What is the type of 10 / 2?
The / operator always returns a double, so the result is 5.0.
3. Which expression safely converts user text to a number with a default?
tryParse returns null for bad text, and ?? supplies the default.
4. Why should you avoid dynamic?
dynamic switches off static type checking.
Learn Flutter & Dart with a mentor
Free lessons get you started. Our Mobile App Development training adds real projects and code reviews from working developers.
- Project-based learning
- Mentor code reviews
- Free counselling call
