use-string-buffers
Same as use_string_buffers in Dart lints
- Group
- Performance
- Path
lint/performance/use-string-buffers- Default
- On (recommended)
- Origin
- Dart lints
- Rule
- 505 of 512
Prefers a StringBuffer to growing a String with + inside a loop.
Strings are immutable, so s += piece in a loop copies the whole string on
every iteration; a StringBuffer appends in amortized constant time. The rule
inspects the statements directly in the body of a for, while or
do-while loop (and plain nested blocks). It reports s += ... when s is
a String variable declared outside that body, and reports s in
s = s + ... or s = '$s...' (parentheses aside), where the right-hand
side starts with s and s is a local variable or parameter: for a field
or top-level variable the analyzer compares the setter written with the
getter read, which never match.
Invalid
String concat(List<String> parts) {
var result = '';
for (final part in parts) {
result += part;
}
return result;
}
String whileLoop(int n) {
String text = '';
var i = 0;
while (i < n) {
text = text + '$i';
i++;
}
return text;
}
String doLoop(int n) {
var text = '';
do {
text = '$text,';
n--;
} while (n > 0);
return text;
}
String classic(int n) {
var s = '';
for (var i = 0; i < n; i++) {
{
s += 'x';
}
}
return s;
}
String interpolatedBraces(List<int> values) {
var s = '';
for (final v in values) {
s = '${s}x$v';
}
return s;
}
class Joiner {
Joiner(this.prefix, this.label);
final String prefix;
final String? label;
// The variables' types come from the enclosing class's fields.
String join(List<String> parts) {
var s = prefix;
for (final part in parts) {
s += part;
}
var t = label ?? '';
for (final part in parts) {
t += part;
}
return s + t;
}
} for (final part in parts) { result += part; while (i < n) { text = text + '$i'; do { text = '$text,'; { s += 'x'; for (final v in values) { s = '${s}x$v'; for (final part in parts) { s += part; for (final part in parts) { t += part;Valid
String buffer(List<String> parts) {
final buffer = StringBuffer();
for (final part in parts) {
buffer.write(part);
}
return buffer.toString();
}
String declaredInside(List<String> parts) {
var last = '';
for (final part in parts) {
var s = '';
s += part;
last = s;
}
return last;
}
int numbers(List<int> values) {
var total = 0;
for (final v in values) {
total += v;
}
return total;
}
String suffix(List<String> parts) {
var s = '';
for (final part in parts) {
s = part + s;
}
return s;
}
String nested(List<String> parts) {
var s = '';
for (final part in parts) {
if (part.isNotEmpty) {
s += part;
}
}
return s;
}
String outside(String s) {
s += '!';
return s;
}
String prefixText(List<String> parts) {
var s = '';
for (final part in parts) {
s = 'x$s';
}
return s;
}Configure use-string-buffers
Set its severity in falcon.json. See the configuration guide.
{
"linter": {
"rules": {
"performance": {
"use-string-buffers": "error"
}
}
}
}Or silence one occurrence with a suppression comment; the reason is required.
// falcon-ignore lint/performance/use-string-buffers: <reason>More performance rules
- avoid-border-allflutter
Avoids Flutter's non-const
Border.allfactory. - avoid-shrink-wrap-in-listsflutter
Avoids shrink-wrapped Flutter lists nested in rows, columns, or other lists.
- avoid-slow-async-io
avoid_slow_async_ioAvoid the slow asynchronous
dart:iofile-system queries. - avoid-slow-collection-methods
Reports filtered iterable searches that have a direct search-method alternative.
- avoid-unnecessary-collections
Avoid singleton collection literals where SDK APIs accept a single value.
- avoid-unnecessary-consumer-widgetsriverpod
Flags Riverpod consumer widgets whose build reference is unused.
- avoid-unnecessary-futures
Prefer synchronous declarations when an async Future only returns scalars.
- avoid-unnecessary-gesture-detectorflutter
Flags handler-free Flutter
GestureDetectorsand tap-only wrappers around enabled Flutter buttons.