I've been converting a package to using non-nullable.
I have code such as:
String readLine({String lineDelimiter = '\n'}) {
var line = '';
line = file.readLine(); // can return null
}
Dart 2.9 of course doesn't like this, so I expect to be able to change my code to:
Note the change from 'var' to 'var?'.
String readLine({String lineDelimiter = '\n'}) {
var? line = '';
line = file.readLine(); // can return null
}
But dart gives me a compile error:
Missing variable type for '';
I don't see why dart would suddenly no longer understand that '' is a string and force me to declare the type.
I cannot reproduce this error. What program gave you this error? Can you supply the command you ran? Neither dart nor dartanalyzer printed the error text you provide, Missing variable type for '';.
$ cat 1030.dart
String readLine({String lineDelimiter = '\n'}) {
var? line = '';
line = file.readLine(); // can return null
}
$ ~/code/dart-sdk/sdk/xcodebuild/ReleaseX64/dart-sdk/bin/dart --enable-experiment=non-nullable 1030.dart
1030.dart:2:8: Error: Expected an identifier, but got '?'.
var? line = '';
^
1030.dart:2:10: Error: Expected ';' after this.
var? line = '';
^^^^
1030.dart:2:10: Error: Setter not found: 'line'.
var? line = '';
^^^^
1030.dart:3:12: Error: Getter not found: 'file'.
line = file.readLine(); // can return null
^^^^
1030.dart:3:5: Error: Setter not found: 'line'.
line = file.readLine(); // can return null
^^^^
1030.dart:1:8: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
String readLine({String lineDelimiter = '\n'}) {
^
$ ~/code/dart-sdk/sdk/xcodebuild/ReleaseX64/dart-sdk/bin/dartanalyzer --enable-experiment=non-nullable 1030.dart
Analyzing 1030.dart...
error • The body might complete normally, causing 'null' to be returned, but the return type is a potentially non-nullable type. • 1030.dart:1:8 • body_might_complete_normally
error • Expected an identifier. • 1030.dart:2:8 • missing_identifier
error • Expected to find ';'. • 1030.dart:2:10 • expected_token
error • Undefined name 'line'. • 1030.dart:2:10 • undefined_identifier
error • Undefined name 'line'. • 1030.dart:3:5 • undefined_identifier
error • Undefined name 'file'. • 1030.dart:3:12 • undefined_identifier
lint • Prefer typing uninitialized variables and fields. • 1030.dart:2:10 • prefer_typing_uninitialized_variables
6 errors and 1 lint found.
Also, since var? is not a legal variable declaration start (like var or final), that may be causing the problem. You can try your program again, removing the ? from var?.
I'm using effective dart so I'm wondering if it is causing the issue. Will test tomorrow.
I've tried to create small standalone project this morning and can't reproduce the error either.
I will have to go back to the original project a try again but will need more time.
Is there any reason why var? isn't supported?
Here is the original method:
String readLine({String lineDelimiter = '\n'}) {
String line = '';
int byte;
var priorChar = '';
var foundDelimiter = false;
while ((byte = _raf.readByteSync()) != -1) {
var char = utf8.decode([byte]);
if (_isLineDelimiter(priorChar, char, lineDelimiter)) {
foundDelimiter = true;
break;
}
line += char;
priorChar = char;
}
if (line.isEmpty && foundDelimiter == false) {
/// this line requires 'line' to be nullable.
line = null;
}
return line;
}
Essentially nnbd is now forcing me to declare the type if I need a local variable to be nullable but the right hand side of the expression is non-nullable.
Allowing 'var?' seems to be a logical extension of how var works.
The code comes from:
pub.dev/packages/dshell/util/file_sync.dart
Currently var? is simply a syntax error, as mentioned by @srawlins. The language team has considered var? as a way to specify that the inferred type of the declared variable should be made nullable, and it was motivated by exactly the situation you describe (where the variable is initialized with a non-nullable value, but is intended to be nullable). It is likely to be delayed because of resource constraints, but it is a non-breaking change so it can still be added later.
For now, you might use var line = null ?? ''; to get the same effect.
The reason var? is not supported is, roughly, that ? is something you add on types, and var is not a type. It's a declaration marker that occurs instead of a type, like final - except that final can also be combined with at type, while var can't.
As Erik says, we have considered whether adding var? would be useful, precisely in the situation where you have var x = someExpression; and you want x to be type of someExpression or null (and you dont' want to have to repeat the type). It's not part of the current plan for null safety, though.
ok, thanks for the explanation.
On Mon, 15 Jun 2020 at 17:20, Erik Ernst notifications@github.com wrote:
Currently var? is simply a syntax error, as mentioned by @srawlins
https://github.com/srawlins. The language team has considered var? as a
way to specify that the inferred type of the declared variable should be
made nullable, and it was motivated by exactly the situation you describe
(where the variable is initialized with a non-nullable value, but is
intended to be nullable). It is likely to be delayed because of resource
constraints, but it is a non-breaking change so it can still be added later.For now, you might use var line = null ?? ''; to get the same effect.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
https://github.com/dart-lang/language/issues/1030#issuecomment-643950746,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAG32OHPQN6LE7S3AUPWJT3RWXDS3ANCNFSM4N5K6UEQ
.