mybatis has the method:
org.apache.ibatis.builder.BaseBuilder#parseExpression(String regex, String defaultValue)
Is this method not used? Is it for subsequent expansion?
protected Pattern parseExpression(String regex, String defaultValue) {
return Pattern.compile(regex == null ? defaultValue : regex);
}
Related
My current goal is to remove this code duplication:
final int? myNullableInt = 10;
/// Everywhere I need to do this null verification:
if (myNullableInt == null) return null;
return someOtherMethodThatReceivesANonNullableInt(myNullableInt);
I want to convert to something like we have in Kotlin:
final int? myNullableInt = 10;
return myNullableInt?.apply((myInt) => someOtherMethodThatReceivesANonNullableInt(myInt));
I did it:
extension ApplyIfNotNull on Object? {
T? apply<T extends Object?>(Object? obj, T? Function(Object) fn) {
if (obj == null) return null;
return fn(obj);
}
}
But this gives me a static error:
The argument type 'Object' can't be assigned to the parameter type 'int'.
Note: this should work with all types, e.g ints, Strings, double and MyOwnClassTypes.
Is there something I can do? or am I missing something?
extension ApplyIfNotNull on Object? {
T? apply<T extends Object?>(Object? obj, T? Function(Object) fn) {
if (obj == null) return null;
return fn(obj);
}
}
That doesn't work because it declares that the callback be capable of accepting any Object argument, but you're presumably trying to use it with a function that accepts only an int argument. It's also unclear why you've made an extension method since it doesn't involve the receiver (this) at all.
You need to make your function generic on the callback's argument type as well:
R? applyIfNotNull<R, T>(T? obj, R Function(T) f) =>
(obj == null) ? null : f(obj);
(That's the same as what I suggested in https://github.com/dart-lang/language/issues/360#issuecomment-502423488 but with the arguments reversed.)
Or, as an extension method, so that it can work on this instead of having the extra obj argument:
extension ApplyIfNotNull<T> on T? {
R? apply<R>(R Function(T) f) {
// Local variable to allow automatic type promotion. Also see:
// <https://github.com/dart-lang/language/issues/1397>
var self = this;
return (self == null) ? null : f(self);
}
}
Also see https://github.com/dart-lang/language/issues/360 for the existing language feature request and for some other suggested workarounds in the meantime.
I must pass int? parameter to method where I can use only String? parameter. How to do it shorter?
void mymethod(String? s)
{
print(s ?? "Empty");
}
int? a = null;
mymethod(a == null ? null : a.toString()); // how do this line easier?
Edit: I can't change parameter mymethod(String? s) to mymethod(int? s) - it still must be String?
I don't know if I understood correctly, but you want this ?
void mymethod(String? s)
{
print(s ?? "Empty");
}
int? a; // this could be null already
mymethod(a?.toString()); // "a" could be null, so if it is null it will be set, otherwise it will be set to String
You could just do this:
mymethod(a?.toString());
But if you want to make the check, my suggestion is to make the function do it.
int? a;
mymethod(a);
void mymethod(int? s) {
String text = "Empty";
if (s != null) text = s.toString();
print(text);
}
literally shorter, "" with $can help, with more complex you need use ${} instead of $.
Example: mymethod(a == null ? null : "$a");
Or you can create an extensiton on Int? and just call extension function to transform to String?, short, easy and reuseable. you can write the extension code elsewhere and import it where you need it.
Try with the following:
void mymethod(int? s) {
return s?.toString;
}
int? a = null;
mymethod(a);
This question already has answers here:
"The operator can’t be unconditionally invoked because the receiver can be null" error after migrating to Dart null-safety
(3 answers)
Closed 12 months ago.
I have migrated my Dart code to NNBD / Null Safety. Some of it looks like this:
class Foo {
String? _a;
void foo() {
if (_a != null) {
_a += 'a';
}
}
}
class Bar {
Bar() {
_a = 'a';
}
String _a;
}
This causes two analysis errors. For _a += 'a';:
An expression whose value can be 'null' must be null-checked before it can be dereferenced.
Try checking that the value isn't 'null' before dereferencing it.
For Bar() {:
Non-nullable instance field '_a' must be initialized.
Try adding an initializer expression, or add a field initializer in this constructor, or mark it 'late'.
In both cases I have already done exactly what the error suggests! What's up with that?
I'm using Dart 2.12.0-133.2.beta (Tue Dec 15).
Edit: I found this page which says:
The analyzer can’t model the flow of your whole application, so it can’t predict the values of global variables or class fields.
But that doesn't make sense to me - there's only one possible flow control path from if (_a != null) to _a += 'a'; in this case - there's no async code and Dart is single-threaded - so it doesn't matter that _a isn't local.
And the error message for Bar() explicitly states the possibility of initialising the field in the constructor.
The problem is that class fields can be overridden even if it is marked as final. The following example illustrates the problem:
class A {
final String? text = 'hello';
String? getText() {
if (text != null) {
return text;
} else {
return 'WAS NULL!';
}
}
}
class B extends A {
bool first = true;
#override
String? get text {
if (first) {
first = false;
return 'world';
} else {
return null;
}
}
}
void main() {
print(A().getText()); // hello
print(B().getText()); // null
}
The B class overrides the text final field so it returns a value the first time it is asked but returns null after this. You cannot write your A class in such a way that you can prevent this form of overrides from being allowed.
So we cannot change the return value of getText from String? to String even if it looks like we checks the text field for null before returning it.
An expression whose value can be 'null' must be null-checked before it can be dereferenced. Try checking that the value isn't 'null' before dereferencing it.
It seems like this really does only work for local variables. This code has no errors:
class Foo {
String? _a;
void foo() {
final a = _a;
if (a != null) {
a += 'a';
_a = a;
}
}
}
It kind of sucks though. My code is now filled with code that just copies class members to local variables and back again. :-/
Non-nullable instance field '_a' must be initialized. Try adding an initializer expression, or add a field initializer in this constructor, or mark it 'late'.
Ah so it turns out a "field initializer" is actually like this:
class Bar {
Bar() : _a = 'a';
String _a;
}
There are few ways to deal with this situation. I've given a detailed answer here so I'm only writing the solutions from it:
Use local variable (Recommended)
void foo() {
var a = this.a; // <-- Local variable
if (a != null) {
a += 'a';
this.a = a;
}
}
Use ??
void foo() {
var a = (this.a ?? '') + 'a';
this.a = a;
}
Use Bang operator (!)
You should only use this solution when you're 100% sure that the variable (a) is not null at the time you're using it.
void foo() {
a = a! + 'a'; // <-- Bang operator
}
To answer your second question:
Non-nullable fields should always be initialized. There are generally three ways of initializing them:
In the declaration:
class Bar {
String a = 'a';
}
In the initializing formal
class Bar {
String a;
Bar({required this.a});
}
In the initializer list:
class Bar {
String a;
Bar(String b) : a = b;
}
You can create your classes in null-safety like this
class JobDoc {
File? docCam1;
File? docCam2;
File? docBarcode;
File? docSignature;
JobDoc({this.docCam1, this.docCam2, this.docBarcode, this.docSignature});
JobDoc.fromJson(Map<String, dynamic> json) {
docCam1 = json['docCam1'] ?? null;
docCam2 = json['docCam2'] ?? null;
docBarcode = json['docBarcode'] ?? null;
docSignature = json['docSignature'] ?? null;
}
}
I have a Dart enum which looks like this:
enum Gender {
#JsonValue(0)
male,
#JsonValue(1)
female,
}
I have created a dart extension that returns the String name and int value. It looks something like this -
extension GenderExtention on Gender {
String get name {
switch (this) {
default:
return _getDefaultName(this);
}
}
//For the enum male, it returns "Male"
String _getDefaultName(Community value) {
if (value == null) {
return null;
}
String valueStr = value.toString();
String enumName = valueStr.substring(valueStr.indexOf('.') + 1);
return enumName[0].toUpperCase() + enumName.substring(1);
}
int get value {
switch (this) {
case Gender.male:
return 0;
case Gender.female:
return 1;
default:
return null;
}
}
}
This becomes painful for larger enums, especially the value section.
Are there any suggestions on how to get the enum value (0 for #JsonValue(0)) more easily than manually defining it in the extension? Would using something like reflections help here?
the only way to access annotations at run-time is indeed reflection using dart:mirrors. That library is not available when compiling to the web or for Flutter, so it's probably not going to solve your problem.
What you can do here is:
int get value => this.index;
That only works if the values are actually the same as the index (0 for the first declared value, 1 for the next, etc.)
How can I use boolean in route definition?
If I use this way,
GET /user/:userName controllers.AppController.user(userName, registerDone:Boolean?=0)
it throws this error:
[error] found : Int(0)
[error] required: Boolean
If I use this way,
GET /user/:userName controllers.AppController.user(userName, registerDone:Boolean?=false)
it throws this error:
bad request at: /user/aajjblack?registerDone=true, Cannot parse
parameter registerDone as Boolean: should be 0 or 1
Controller:
public static Result user(final String userName, Boolean registerDone) {
}
Use... Int instead
GET /user/:userName controllers.AppController.user(userName, registerDone: Int?=0)
action:
public static Result user(final String userName, int registerDone) {
if(registerDone == 0){
return badRequest();
}
// do something with registered user...
return ok();
}
It's simplest replace of any kind of booleans, as you can just check if registerDone is bigger than 0 (and it still keeps type-safety).