How to declare a variable depending on if statement in Dart like in Kotlin? - flutter

How to declare a variable depending on if statement in Dart? In Kotlin it would look like this:
val max = if (a > b) {
a
} else {
b
}
Is it even possible in Dart?

#pskink's answer in the comment is correct but it didn't show how you would be able to do it in this scenario. Here is how you can do it in your scenario:
final max= a > b ? a : b;
The final keyword in Dart is the same as the val keyword in Kotlin. You will not be able to change the value of the variable. You could also use the var keyword in Dart which is the same as Kotlin's var keyword. You will be able to change the value of the variable after declaring it. You might be confused with the one-liner code since there isn't any if or else statements inside it. The code above is called a ternary operator.
Here is an explanation for it:
(condition/expresssion) ? val1(if true execute this) : val2(if false execute this)

For more than one statement, we can use a method by declaring its type as int.
void main() {
print(declareVariable());
}
int a = 10;
int b = 30;
int declareVariable() {
if(b < a){
return 1;
}
else if(b > a) {
return 2;
}
else {
return 0;
}
}
Edited :
We can declare more then one condition in single line in the same way.
var singleLine = b < a ? 1 : b > a ? 2 : 0;
This will print out the same answer as method.

Related

Flutter : PieChart Error: The argument type 'RxInt' can't be assigned to the parameter type 'double?' [duplicate]

Very simple issue. I have the useless class:
class Useless{
double field;
Useless(this.field);
}
I then commit the mortal sin and call new Useless(0);
In checked mode (which is how I run my tests) that blows up, because 'int' is not a subtype of type 'double'.
Now, it works if I use new Useless(0.0) , but honestly I spend a lot of time correcting my tests putting .0s everywhere and I feel pretty dumb doing that.
As a temporary measure I rewrote the constructor as:
class Useless{
double field;
Useless(num input){
field = input.toDouble();
}
}
But that's ugly and I am afraid slow if called often. Is there a better way to do this?
Simply toDouble()
Example:
int intVar = 5;
double doubleVar = intVar.toDouble();
Thanks to #jamesdlin who actually gave this answer in a comment to my previous answer...
In Dart 2.1, integer literals may be directly used where double is expected. (See https://github.com/dart-lang/sdk/issues/34355.)
Note that this is syntactic sugar and applies only to literals. int variables still won't be automatically promoted to double, so code like:
double reciprocal(double d) => 1 / d;
int x = 42;
reciprocal(x);
would fail, and you'd need to do:
reciprocal(x.toDouble());
You can also use:
int x = 15;
double y = x + .0;
use toDouble() method.
For e.g.:
int a = 10
print(a.toDouble)
//or store value in a variable and then use
double convertedValue = a.toDouble()
From this attempt:
class Useless{
double field;
Useless(num input){
field = input.toDouble();
}
}
You can use the parse method of the double class which takes in a string.
class Useless{
double field;
Useless(num input){
field = double.parse(input.toString()); //modified line
}
}
A more compact way of writing the above class using constructor's initialisers is:
class Useless{
double _field;
Useless(double field):_field=double.parse(field.toString());
}
Since all divisions in flutter result to a double, the easiest thing I did to achieve this was just to divide the integer value with 1:
i.e.
int x = 15;
double y = x /1;
There's no better way to do this than the options you included :(
I get bitten by this lots too, for some reason I don't get any warnings in the editor and it just fails at runtime; mighty annoying :(
I'm using a combination:
static double checkDouble(dynamic value) {
if (value is String) {
return double.parse(value);
} else if (value is int) {
return 0.0 + value;
} else {
return value;
}
}
This is how you can cast from int to double
int a = 2;
double b = a*1.0;

Type 'Int' does not conform to protocol 'BooleanType'?

I know there is another thread with the same question, but it doesn't tell what is actually causing the problem
Im new to swift, so Im a bit confused on this.
I wrote a very simple program that is supposed to start with a default number of followers (0) and assign that to 'defaultfollowers' and once that becomes 1 its supposed become "followers", but I get the error "Type 'Int' does not conform to protocol 'BooleanType'". What is causing this and why
var followerdeafault = 0
var followers = 0
if (followerdeafault++){
var followers = followerdeafault
}
In Swift you can't implicitly substitute Int instead of Bool. This was done to prevent confusion and make code more readable.
So instead of this
let x = 10
if x { /* do something */ }
You have to write this:
let x = 10
if x != 0 { /* do something */ }
Also you can't pass an Optional instead of Bool to check if it's nil, as you would do in Objective-C. Use explicit comparison instead:
if myObject != nil { /* do something */ }
As the comments said, you're trying to use an Int in a Bool comparison statement. What you're looking for is probably something like this:
if followerdeafuaut++ == 1 { ... }
Also side note: the ++ operator is deprecated, moving towards using +=

Simple Pointer Operations in Swift?

Let's say I do the following in C++:
int i = 1;
int* ptr = &i;
*ptr = 2;
cout << i << '\n';
And I want to do something similar in swift. Could I do the following?
var i : Int = 1
var iptr : UnsafeMutablePointer<Int> = &i
iptr.memory = 2
print(i)
And achieve the same result?
Yes-ish.
You can't do it exactly as you've attempted in the question. It won't compile. Swift won't let you directly access the address of a value like this. At the end of the day, the reason is mostly because there's simply no good reason to do so.
We do see the & operator in Swift however.
First of all, there is the inout keyword when declaring function parameters:
func doubleIfPositive(inout value: Float) -> Bool {
if value > 0 {
value *= 2
return true
}
return false
}
And to call this method, we'd need the & operator:
let weMadeARadian = doubleIfPositive(&pi)
We can see it similarly used when we have a function which takes an argument of type UnsafeMutablePointer (and other variants of these pointer structs). In this specific case, it's primarily for interoperability with C & Objective-C, where we could declare a method as such:
bool doubleIfPositive(float * value) -> bool {
if (value > 0) {
value *= 2;
return true;
}
return false;
}
The Swift interface for that method ends up looking somethin like this:
func doubleIfPositive(value: UnsafeMutablePointer<Float>) -> Bool
And calling this method from Swift actually looks just like it did before when using the inout approach:
let weMadeARadian = doubleIfPositive(&pi)
But these are the only two uses of this & operator I can find in Swift.
With that said, we can write a function that makes use of the second form of passing an argument into a method with the & operator and returns that variable wrapped in an unsafe mutable pointer. It looks like this:
func addressOf<T>(value: UnsafeMutablePointer<T>) -> UnsafeMutablePointer<T> {
return value
}
And it behaves about as you'd expect from your original code snippet:
var i: Int = 1
var iPtr = addressOf(&i)
iPtr.memory = 2
print(i) // prints 2
As noted by Kevin in the comments, we can also directly allocate memory if we want.
var iPtr = UnsafeMutablePointer<Int>.alloc(1)
The argument 1 here is effectively the mount of space to allocate. This says we want to allocate enough memory for a single Int.
This is roughly equivalent to the following C code:
int * iPtr = malloc(1 * sizeof(int));
BUT...
If you're doing any of this for anything other than interoperability with C or Objective-C, you're most likely not Swifting correctly. So before you start running around town with pointers to value types in Swift, please, make sure it's what you absolutely need to be doing. I've been writing Swift since release, and I've never found the need for any of these shenanigans.
Like this (not the only way, but it's clear):
var i : Int = 1
withUnsafeMutablePointer(&i) {
iptr -> () in
iptr.memory = 2
}
print(i)
Not a very interesting example, but it is completely parallel to your pseudo-code, and we really did reach right into the already allocated memory and alter it, which is what you wanted to do.
This sort of thing gets a lot more interesting when what you want to do is something like cycle thru memory just as fast as doing pointer arithmetic in C.

do nothing in If inside swift

I am wondering inside of a if statement, can I have something like Python pass?
var num = 10
num > 5 ? doSomethingIfTrue(): doSomethingIfFalse()
The above code will be alright if both true and false methods are supplied.
What if I only wanna to execute just the true method??
Such as:
num > 5 ? doSomethingIfTrue(): ***pass***
I am hoping to have something like a pass statement in swift so the program will just carry on if false is return. I have tried continue and fallthrough but I guess they are only used inside a loop statement.
You could, in theory, say this:
var num = 10
num > 5 ? doSomethingIfTrue() : ()
That works because () is a void statement.
But I wouldn't do that! I would write it this way:
var num = 10
if num > 5 { doSomethingIfTrue() }
Yes, it's more characters, but that's Swift; you can't omit the curly braces from an if construct. And your ternary operator was the wrong operator to start with. As someone else has pointed out, it really is most appropriate for conditional assignment and similar.
Really, it's a matter of adapting yourself to the syntax, operators, and flow control of this language. Don't to try to make Swift be like Python; it won't be.
The ?: conditional operator expects a value in each of its three operands, because it needs to give a value back. Say you have the hypothetical
a = b + ((c > 0) ? 1 : pass)
What would you expect the + to do if c was not positive?
For statements, use if as follows:
if num > 5 {
doSomethingIfTrue()
}
I agree with the other answers that this is probably something best avoided, since the ternary operator's purpose is to evaluate to a value in both cases – you really just want an if.
However, if you really want to do it, you can match the void return type of doSomethingIfTrue() with ().
This isn’t generic across all possibilities though. If doSomethingIfTrue() didn’t return void but instead returned an Int, it wouldn’t work. You’d have to use 0 or something similar instead.
This will work (depending on your definition of work):
let pass: Any = ()
func doSomething() { }
func doSomethingElse() -> String { return "a" }
func doSomethingNumeric() -> Int { return 1 }
var num = 5
num > 5 ? doSomething() : pass
num > 5 ? doSomethingElse() : pass
num > 5 ? doSomethingNumeric() : pass
If you ever use the value returned by these expressions, they’ll be an Any.
Don’t use this :-)
Why would you use a ternary operator for an empty else in a ternary statement? It is much more complicated and inefficient. Try this:
var num = 10
if num > 5 {
println("hi")
}
or
var num = 10
num > 5 ? doSomethingIfTrue(): pass()
Create pass() and have it do nothing, or print that we did nothing.

Returning Multiple Values from a Function

Hey, so I'm making an iPhone app and in there is a common function that needs to be called. So I put it in it's own file and set it up, passing the parameters to that and all that. However, I'm not sure how best to return the values from the function. I read up trying to return the values in an array, but I'm not sure how to do it.
int EndOfTurn(int varTurns, int varFatness)
{
varTurns--;
if (varTurns <= 0) {
varFatness = varFatness - 5;
}
else {
varFatness += 2;
}
}
I need to return both varTurns and varFatness. However, this function will become more complicated, with me returning as many as 10 variables.
As of now, it is written in C, not Objective-C, (I just added a .c file to the Project), but I can change that. It needs to simply return all the updated values that I used in the function. If you could, write up the declaration of the function and the type:
TYPE_HERE EndOfTurn(int varTurns, int varFatness)
so I know exactly how to do it. Thanks, and I hope I gave enough info!
Your options are essentially the same in Objective-C as in conventional C:
Use reference parameters, or
Return some kind of data structure (a struct, a class instance) that encapsulates the collection of values you want to return.
For example:
void EndOfTurn(int* varTurns, int* varFatness) { ... }
or
typedef struct { int turns, int fatness } ReturnType;
ReturnType EndOfTurn(int varTurns, int varFatness) {
ReturnType foo;
foo.turns = varTurns-1;
if (foo.turns <= 0) {
foo.fatness = varFatness - 5;
}
else {
foo.fatness = varFatness + 2;
}
return foo;
}
or
typedef struct { int turns, int fatness } ReturnType;
void EndOfTurn( ReturnType* param ) {
param->turns--;
if (param->turns <= 0) {
param->fatness -= 5;
}
else {
param->fatness += 2;
}
}
I'd suggest that you find a good tutorial on pointers in C (perhaps this one or this one?) and take some quality time reading over it. The concepts also apply to Objective-C, and are pretty fundamental to how both languages work. It's a bit beyond the scope of a Stack Overflow answer, and you'll really need to be comfortable with them.
Personally, I would do it the objective-c way, and pass an NSDictionary out of the function. Something like:
(NSDictionary *)EndOfTurn:(int)varTurns withFatness:(int)varFatness
{
varTurns--;
if (varTurns <= 0) {
varFatness = varFatness - 5;
}
else {
varFatness += 2;
}
return [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:varFatness],#"FATNESS", [NSNumber numberWithInt:varTurns],#"TURNS",nil];
}
It feels good as long as you keep your keys consistent.
You access your returned dictionary like so:
int varTurns = [returnedDict objectForKey:#"TURNS"];
if you want an example in C you pass pointers to those two variables are parameters so your function signature would look something like this:
void EndOfTurn(int* varTurns, int* varFatness);
Then when modifying the values of those you just dereference them:
*varTurns = *varTurns - 5;
or whatever you need to do.
The original function call would look like this:
int otherFunctionVarTurns;
int otherFunctionVarFatness;
...
EndOfTurns(&otherFunctionVarTurns, &otherFunctionVarFatness);
Since you've added a C tag, here's how you could do it in plain C (though this may not be the most idiomatic way to do it in Objective-C):
struct turn_state {
int varTurns;
int varFatness;
};
void EndOfTurn(struct turn_state *state)
{
state->varTurns--;
if (state->varTurns <= 0) {
state->varFatness -= 5;
} else {
state->varFatness += 2;
}
}
Use a struct turn_state variable to store the current state, and call it like so:
struct turn_state current_state = { /* initial values */ };
/* ...code... */
EndOfTurn(&current_state);
Adding more variables is simple - just add them to the struct turn_state.