I just stand in front of a very weird part in dart, I didn't find an answer on the internet, No truthy and falsy values in dart?!
for example,
const x = "foo";
void main(){
if(x){
print("x is set")
}
}
In JavaScript we do this things very easily, how can I do that in Dart?!
Dart is a statically typed language, so x is a String, and you can't check if a string is true or false.
if you want to check if x has a value or not, you can do the following
String x = 'hi';
if (x?.isNotEmpty ?? false) {
print("x is set");
}
After some researches, I've found that in order to check for a dynamiclly assigned variable, where in case you're not sure if the variable will be set to a number or a string for example, you need to check if the variable is not equal to null.
For example:
void main(){
var a;
if(true){
a = "The variable is set to string";
}
else if(false){
a = 12; //the variable is set to a number
}
//Now, to check:
if(a != null){
print("A is set, WOW Dart is working! I thought it's garbage!");
}
}
In case the both statements are false, the variable will still be a null.
Related
I’m trying to get the variable name instead of the value to pass it to another method
eg.
String myString = "xyz";
String getVariableName(String s){
// What i want is if the above string is passed [getVariableName(myString)]
//i want it to return ['myString']
}
This is generally not possible. At best, if there are a finite number of String variables you care about, you could manually make a collection of them, and then search it:
final stringVariables = <String, String Function()>{
'myString': () => myString,
'myOtherString': () => myOtherString,
};
var myString = 'xyz';
var myOtherString = 'abc';
String getVariableName(String s) {
for (var entry in stringVariables.entries) {
if (entry.value() == s) {
return entry.key;
}
}
return '';
}
void main() {
print(getVariableName('xyz')); // Prints: myString
myString = 'foo';
print(getVariableName('foo')); // Prints: myString
}
Note that stringVariables's above must use a Function as a thunk to delay evaluation of the variable; otherwise the variable name would be associated with whatever value it happened to have when stringVariables is first accessed and wouldn't work if your variables are reassigned.
All that said, I don't really recommend doing any of this. This sounds like an XY problem. You should be asking about whatever it is you ultimately want to do, and there probably is a better way to accomplish that task.
I keep getting this error => "The operator '+' isn't defined for the type 'Object'. (view docs). Try defining the operator '+'."
How could I define it?
import 'dart:math';
bool isArmstrongNumber(int number) {
var numberString = number.toString();
return number ==
numberString.split("").fold(0,
(prev, curr) => prev! + pow(int.parse(curr), numberString.length));
}
main() {
var result = isArmstrongNumber(153);
print(result);
}
fold in Dart can have some problems when it comes to automatically determine what type it should return and handle. In these cases, we need to manually enter the type like this (fold<int>()):
import 'dart:math';
bool isArmstrongNumber(int number) {
final numberString = number.toString();
return number ==
numberString.split("").fold<int>(
0,
(prev, curr) =>
prev + pow(int.parse(curr), numberString.length).toInt(),
);
}
void main() {
final result = isArmstrongNumber(153);
print(result); // true
}
I also fixed a problem where pow returns num which is a problem. In this case, we can safely just cast it to int without issues.
Details about this problem with fold
The problem here is that Dart tries to guess the generic of the fold based on the expected returned type of the method. Since the == operator expects an Object to compare against, fold will also expect to just return Object and the generic ends up being fold<Object>.
This is not a problem for the first parameter since int is an Object. But it becomes a problem with your second argument where you expect an int object and not Object since Object does not have the + operator.
I just started programming and I have struggle understanding functions with return value. I tried for example to make function that returns the absolute value of a real number:
include
double absol(double x) {
if (x>0) {
return (x);
}
else {
return (-x);
}
}
main() {
double x;
scanf("%fl",&x);
printf("%f",absol(x));
}
It give zero back and if I change the initial value of x, it gives this value back. Why doesn't it take the value that I input with scanf?
Thank you.
scanf("%fl",&x); will not correctly read in a double. You need scanf("%lf",&x); instead.
I am trying to write a function that takes two arguments: givenType and targetType. If these two arguments match, I want givenType to be returned, otherwise null.
For this objective, I am trying to utilize Dart's is expression (maybe there is a better way to go about it, I am open to suggestions). Initially, I thought it would be as simple as writing this:
matchesTarget(givenType, targetType) {
if (givenType is targetType) {
return givenType;
}
return null;
}
But this produces an error:
The name 'targetType' isn't a type and can't be used in an 'is'
expression. Try correcting the name to match an existing
type.dart(type_test_with_non_type)
I tried looking up what satisfies an is expression but cannot seem to find it in the documentation. It seems like it needs its right-hand operand to be known at compile-time (hoping this is wrong, but it does not seem like I can use a variable), but if so, how else can I achieve the desired effect?
I cant guess the purpose of the function (or the scenario where it would be used, so if you can clarify it would be great). First of all, I don't know if you are passing "types" as arguments. And yes, you need to specify in compile time the right hand argument of the is function.
Meanwhile, if you are passing types, with one change, you can check if the types passed to your function at runtime.
matchesTarget(Type givenType, Type targetType) {
print('${givenType.runtimeType} ${targetType.runtimeType}');
if (givenType == targetType) {
return givenType;
}
return null;
}
main(){
var a = int; //this is a Type
var b = String; //this is also a Type
print(matchesTarget(a,b)); //You are passing different Types, so it will return null
var c = int; //this is also a Type
print(matchesTarget(a,c)); //You are passing same Types, so it will return int
}
But if you are passing variables, the solution is pretty similar:
matchesTarget(givenVar, targetVar) {
print('${givenVar.runtimeType} ${targetVar.runtimeType}');
if (givenVar.runtimeType == targetVar.runtimeType) {
return givenVar.runtimeType;
}
return null;
}
main(){
var a = 10; //this is a variable (int)
var b = "hello"; //this is also a variable (String)
print(matchesTarget(a,b)); //this will return null
var c = 12; //this is also a variable (int)
print(matchesTarget(a,c)); //this will return int
}
The Final Answer
matchesTarget(givenVar, targetType) {
print('${givenVar.runtimeType} ${targetType}');
if (givenVar.runtimeType == targetType) {
return givenVar;
}
return null;
}
main(){
var a = 10; //this is a variable (int)
var b = String; //this is a type (String)
print(matchesTarget(a,b)); //this will return null because 'a' isnt a String
var c = int; //this is also a type (int)
print(matchesTarget(a,c)); //this will return the value of 'a' (10)
}
The as, is, and is! operators are handy for checking types at runtime.
The is operator in Dart can be only used for type checking and not checking if two values are equal.
The result of obj is T is true if obj implements the interface specified by T. For example, obj is Object is always true.
See the below code for an example of how to use the is operator
if (emp is Person) {
// Type check
emp.firstName = 'Bob';
}
Even the error message that you're getting says that
The name 'targetType' isn't a type and can't be used in an 'is'
expression.
So the bottomline is that you can use is only for checking if a variable or value belongs to a particular data type.
For checking equality, you can use the == operator if comparing primitive types, or write your own method for comparing the values. Hope this helps!
I would like to check if a value in dart is an Enum, and if so, serialize it automatically.
My sticking point is how to test if a value is an enum.
This is how I am testing for other types
if (T == int)
val = prefs.getInt(this._key);
else if (T == double)
val = prefs.getDouble(this._key);
else if (T == bool)
val = prefs.getBool(this._key);
else if (T == String)
val = prefs.getString(this._key);
else if ([""] is T)
val = prefs.getStringList(this._key);
but I cannot seem to compare T to an enum
Since all enums have the same methods I was hoping to sense them and handle them accordingly
As of late 2021, all enums extend Enum
You can now finally use is Enum directly:
enum MyEnum {one, two, three}
var x = "a";
var y = MyEnum.one;
print(x is Enum); // false
print(y is Enum); // true
Which also means you can now create extensions for enums:
extension EnumExtension on Enum { ... }
If you need to check is dynamic value enum type. You can use the next approach. The main idea is quite similar to #Oniya Daniel's answer.
enum Fruit {
banana,
apple,
orange,
}
Next method to check isEnum condition
bool isEnum(dynamic data) {
final split = data.toString().split('.');
return split.length > 1 && split[0] == data.runtimeType.toString();
}
Test result below
test('check enum runtime', () {
expect(isEnum(Fruit.banana), true);
expect(isEnum(null), false);
expect(isEnum(''), false);
expect(isEnum('banana'), false);
});
P.S.: to get enum String value good to use describeEnum(<enum_value>) from the package:flutter/foundation.dart
I don't have enough reputation to comment, or I would have added a statement to the answer by #Dmitry Puzak. In Dmitry's method, if data is passed as the String "String.3.0.1", for instance, the method will incorrectly identify the parameter as an enum. The flutter-provided method, describeEnum, attempts to check that it's parameter is an enum and throws an exception if it's not, but in my experience the exception isn't always thrown when the parameter to describeEnum is a String value containing dots.
For a project I'm working, I modified Dmitry's isEnum method to the following, adding the first if block inside the method:
bool isEnum(dynamic data) {
if (data.runtimeType == "".runtimeType) {
return false;
}
final split = data.toString().split('.');
return split.length > 1 && split[0] == data.runtimeType.toString();
}
This makes sure to return false for any String parameter.
I can't offhand think of any other instance where the runtime type of a variable could possibly match the first part of the split done on the toString() return value.
Convert the enum to a list and check if the list contains the value you intend to check.
enum ObjectType {
TypeA, TypeB
}
// checking against enum values
print(ObjectType.values.contains(ObjectType.TypeA)); // true
print(ObjectType.values.contains(ObjectType.TypeB)); // true
// checking against string value
print(ObjectType.values.contains("ObjectType.TypeA")); // false
// checking against boolean
print(ObjectType.values.contains(false)); // false
// checking against int
print(ObjectType.values.contains(234)); // false
// checking against double
print(ObjectType.values.contains(2.345)); // false