Why does this require an if statement to execute - enums

In the swift book by Apple, there is an enum example. It lets you convert a raw Int to a enum rank. However when I try to remove the if statement, the code gives me
Playground execution failed: error: :30:13: error: 'Rank?' does not have a member named 'simpleDesciption'
enum Rank: Int {
case Ace = 1
case Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten
case Jack, Queen, King
func simpleDesciption() -> String {
switch self {
case .Ace:
return "ace"
case .Jack:
return "jack"
case .Queen:
return "queen"
case .King:
return "king"
default:
return String(self.toRaw())
}
}
}
if let convertedRank = Rank.fromRaw(1){
let threeDescription = convertedRank.simpleDesciption()
}
// Why does it need to be wrapped in a if statement?
let convertedRank = Rank.fromRaw(1)
let threeDescription = convertedRank.simpleDesciption()

The if let construct allows to unwrap an optional type. The Rank.fromRaw returns the Rank? optional type, which means it could either be nil or an actual value of the type.
There are two ways to unwrap the value of an optional type in Swift, one of which is the if let construct. The body of the if let is executed if the optional type is not nil, and the variable that follows if let is bound to its value (and thus has type Rank, not Rank?).
Note that if you simply write let convertedRank = Rank.fromRaw(1) without the if, convertedRank has the type Rank? and, again, cannot be directly used as a Rank without being unwrapped.
If you are sure that the value will never be nil, you can force-unwrap it by suffixing the variable name with !:
let convertedRank = Rank.fromRaw(1)
convertedRank!.simpleDescription()
But this is not recommended style, as it will fail at runtime if the value is not defined.

Related

Confusion in Validating References with Lifetimes in Rust [duplicate]

This question already has answers here:
Why are explicit lifetimes needed in Rust?
(10 answers)
Semantics of lifetime parameters
(2 answers)
Closed 6 months ago.
I am a beginner in rust, following rust-lang/book.
In it's ch10.3. Validating References with Lifetimes there is a Listing 10-20:
fn main() {
let string1 = String::from("abcd");
let string2 = "xyz";
let result = longest(string1.as_str(), string2);
println!("The longest string is {}", result);
}
fn longest(x: &str, y: &str) -> &str { // <-- ERROR
if x.len() > y.len() {
x
} else {
y
}
}
There are two points they have mentioned :
Rust can’t tell whether the reference being returned refers to x or y. // <-- no need, according to me
We also don’t know the concrete lifetimes of the references that will be passed in, to determine whether the reference we return will always be valid.
In the code below, their is no error (as expected) :
fn main() {
let string1 = String::from("abcd") ;
let string2 = "xyz";
let x: &str = &string1.as_str();
let y: &str = &string2;
let result =
if x.len() > y.len() {
x
} else {
y
};
println!("The longest string is {}", result);
}
Confusion :
Why Rust need to tell whether the reference being returned refers to x or y ?
Silly question, but I want to know...
Edited
Solution :
Suppose that function call is call by customer, and
function as the seller
In snippet one,
Then, function call expect that it will get one of the value, passed in argument, in return (as in snippet one)
But, if seller is biased or accidently give value other than parameters. like -
fn longest(x: &str, y: &str) -> &str {
let z = "Other String";
&z
}
Then, both function call and function both will get error message
But, their is no any mistake of customer.
Therefore, Rust ensure that customer will not get any error, for the mistake of seller, with the help of annotating lifetime parameter.
This is also the reason of, "Why Typescript introduced in Javascript".
In snippet two,
Both customer and seller is the same function
The related question, mentioned below
Why are explicit lifetimes needed in Rust?
In the second snippet, the lifetime used is the shorter of x and y.
But Rust does not do lifetime inference (or any inference at all) across function boundaries. It always requires you to specify explicitly the types and lifetimes involved. Thus, the lifetime that was inferred in the second snippet needs to be specified explicitly in the first.
The most important reason for that is to avoid unintentional breakage. If functions' type would be inferred it would be too easy to break APIs accidentally. Thus Rust by design requires you to specify signatures explicitly.
First Case
Suppose that Rust didn't give an error with your definition of longest(). Then it's possible to use longest() such that the returned address is stored in a variable that has a longer lifetime than the string slices passed in. For example, something like this:
let result: &str;
{
let x = String::from("welcome");
let y = String::from("bye");
result = longest(&x, &y);
} // `x` and `y` go out of scope, so `&x` and `&y` are no longer valid.
// This would be undefined behavior, because the data pointed to
// by `result` is no longer valid.
println!("result: {}", result);
Since result is used after x and y go out of scope, and result points to the data in either x or y, this would lead to undefined behavior. But Rust doesn't allow this; instead, the Rust compiler forces you to make the returned value of longest() has a sufficiently long lifetime.
So if the compiler didn't give an error with how you wrote longest(), then yes in your example there wouldn't be undefined behavior (because x, y, and result all have the same lifetime), but in general certain invocations of longest() and variables subsequently going out of scope could lead to undefined behavior. So to prevent this, Rust forces you to annotate the lifetimes to make sure the returned address has a long enough lifetime.
Second Case
The variables x, y, and result are all cleaned up at the same time when they go out of scope. So the address referenced by result is always valid whether it's the address of x or the address of y. So there's no error.

Swift3 - how to check whether a variable exists in enum and cast its type

Here's a simple enum of mixed-type cases:
enum Options {
case width
case height
case gravity
}
Both width and height can only have a type of Int however the last one - gravity - can only hold a type of String for example "north" or "south-east".
How to check wether a given variable exists in that enum and also cast its value to a certain type?
Say I have an array:
let arr:Array = ["width", "12"]
I would like to check if arr[0] ("width") exists in my enum and if so convert the second element arr[1] ("12") to an appropriate type (Int in that case).
When I explicitly set enum's type to String like so:
enum Options:String
than I can perform my check:
if Options(rawValue: arr[0]) != nil
That's far from ideal because as mentioned earlier my enum should hold cases of mixed types.
Is there a way to associate an explicit type with a case inside my enum so when I know that arr[0] exists in enum I can cast arr[1] to that type?

Stop Rounding with NSExpression in Calculator [duplicate]

I want to calculate a string, which I'm doing by this:
NSExpression *expression = [NSExpression expressionWithFormat:calculationString];
float result = [[expression expressionValueWithObject:nil context:nil] floatValue];
NSLog(#"%f", result);
The problem is, when calculationstring is 1/2, the result is 0. I tried to change float with double and NSNumber and the %f to %f and %#, but I always just get 0. What to I have to change?
Also if it matters, I am in Europe, so I have commas instead of points for this value, but it shouldn't matter as I am logging with %f which shows it as points. Just for information
Basically, you just need to tell it that you are performing floating point operation,
1.0/2
1.0/2.0
1/2.0
Will all work
Typing in NSExpression is much like in C: literals that look like integers (no decimal point/comma) are treated as integers and thus use integer division. (Under integer division, 1/2 is zero. If you want 0.5, you need floating point division.) This happens when the expression is parsed and evaluated, so attempting to change the type of the result or the formatting of the output has no effect -- those things happen after parsing and evaluation.
If your calculationString is entirely under your control, it's easy to make sure that you use floating point literals anywhere you want floating point division. (That is, use 1.0/2 instead of 1/2.) If not, you'll need to change it such that it does -- here it's probably better to decompose the parsed NSExpression and change an operand rather than munge the string.
Followup edit on the "decompose" bit: String munging in content that you know to have higher-order structure is generally problematic. And with NSExpression, you already have a parser (who's smarter than a simple regex) decomposing the string for you — that is in fact what NSExpression is all about.
So, if you're working with a user-provided string, don't try to change the expression by changing the string. Let NSExpression parse it, then use properties of the resulting object to pick it apart into its constituent expressions. If your string is simply "1/2", then your expression has an array of two arguments and the function "divide:by:" — you can replace it with an equivalent function where one of the arguments is explicitly a floating-point value:
extension NSExpression {
var floatifiedForDivisionIfNeeded: NSExpression {
if function == "divide:by:", let args = arguments, let last = args.last,
let firstValue = args.first?.constantValue as? NSNumber {
let newFirst = NSExpression(forConstantValue: firstValue.doubleValue)
return NSExpression(forFunction: function, arguments: [newFirst, last])
} else {
return self
}
}
}
I think You need to User DDMathParser Which is best in this situation. I have used it in One of my project which is facing same problem as you have faced
DDMathEvaluator *eval = [DDMathEvaluator defaultMathEvaluator];
id value=[eval evaluateString:#"1/2" withSubstitutions:nil error:&error];
NSLog(#"Result %#",value);
Result 0.5
Rickster's solution worked, but had problems with expressions like 5*5/2, where the first argument (here 5*5) was not just a number.
I found a different solution here that works for me: https://stackoverflow.com/a/46554342/6385925
for people who still have this problem i did a somewhat quick fix:
extension String {
var mathExpression: String {
var returnValue = ""
for value in newString.components(separatedBy: " ") {
if value.isOperator {
returnValue += value
} else {
returnValue += "\(Double(value) ?? 0)"
}
}
return returnValue
}
var isOperator: Bool {
["+", "-", "/", "x", "*"].contains(self)
}
}

What is recursive enums and syntax inderect in swift

Swift 2.0 has new feature called indirectly recursive enum. Can someone explain what it is?
From Swift Docs
A recursive enumeration is an enumeration that has another instance of the enumeration as the associated value for one or more of the enumeration cases.
The example given highlights a simplified use case:
indirect enum ArithmeticExpression {
case Number(Int)
case Addition(ArithmeticExpression, ArithmeticExpression)
case Multiplication(ArithmeticExpression, ArithmeticExpression)
}
func evaluate(expression: ArithmeticExpression) -> Int {
switch expression {
case .Number(let value):
return value
case .Addition(let left, let right):
return evaluate(left) + evaluate(right)
case .Multiplication(let left, let right):
return evaluate(left) * evaluate(right)
}
}
// evaluate (5 + 4) * 2
let five = ArithmeticExpression.Number(5)
let four = ArithmeticExpression.Number(4)
let sum = ArithmeticExpression.Addition(five, four)
let product = ArithmeticExpression.Multiplication(sum, ArithmeticExpression.Number(2))
print(evaluate(product))
// prints "18"

Linq how parameters are passed in select

I am learning LINQ and I found this example.
int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
var numsInPlace = numbers.Select((num, index) => new { Num = num, InPlace = (num == index) });
Console.WriteLine("Number: In-place?");
foreach (var n in numsInPlace)
{
Console.WriteLine("{0}: {1}", n.Num, n.InPlace);
}
I don't understand execution of the below line:
var numsInPlace = numbers.Select((num, index) => new { Num = num, InPlace = (num == index) });
As per my understanding num and index are parameters, but I don't understand where we decide that first parameter will be a number and second parameter will be index of the number?
Is it something that is fixed for int type of arrays?
Can anybody please help me understanding this?
Thanks in advance.
The definition of method Select decides it.
There are at lest 2 definitions for Select and one says it takes Func<MyInput,int,MyReturn>. We know that all but the last generic parameter of Func are inputs, and the last one is output.
Func is a special type of object (type of delegate) that has a method called Invoke() to run it and a special syntax-sugar - shorthand () which says that you can omit the Invoke and just write ().
Func<object, int> d = x => 1
d.Invoke(null) // will always return 1
d(new Object()) // also the same
So compiler takes your function and tries to find one of Selects that can accept this kind of function. Then it compiles. And then in run-time the Select just takes first, second etc. element from collection and runs your function by passing the element (and the index if the overload of Select with the function that accepts index has been chosen).
(num, index, TResult) => new { .... } is an anonymous function of type Func delegate.
It is defined by .Net Framework. Thus the First parameter is an object, where as second parameter is index of an object in an array.
Func<T, Index, TResult> Delegate
Func translated to English is: “A method that takes an T and Index of T in an array, and returns a TResult.
There is another thing called Action delegate, where there is no return.
Please have a reference to this link:
http://simpleprogrammer.com/2010/09/24/explaining-what-action-and-func-are/
See this link.
The first argument to selector represents the element to process. The second argument to selector represents the zero-based index of that element in the source sequence. This can be useful if the elements are in a known order and you want to do something with an element at a particular index, for example. It can also be useful if you want to retrieve the index of one or more elements.

Resources