I need to set a variable depending on a condition. But since variables are immutable, I find myself in a sticky situation having to repeat code. What I'd like to do is:
def doSomething(x:Int):Int = {
if(x==1){
val player="Andy"
} else {
val player="Rob"
}
getSomeValue(player) // Another function
}
But the variable "player" is no longer in scope. Only way I see is to call the function "getSomeValue" in both the condition blocks, but that's not something I'd like to do. How do I get around this using immutable variables?
def doSomething(x:Int):Int = {
val player = if(x==1){
"Andy"
} else {
"Rob"
}
getSomeValue(player)
}
Related
Since the Xcode 10.2 (Swift 5) the defer statement at the end of the deinit scope produces:
'defer' statement before end of scope always executes immediately; replace with 'do' statement to silence this warning
Let's take a look at this example:
var foo: String {
didSet {
// smt
}
}
deinit {
defer { <--- Warning
foo = bar
}
}
Of course it's possible to get rid of this warning by moving the code from the observer to a method and call it explicitly but…
What's the point of this warning? - Isn't it reasonable to have the defer statement in the deinit? (e.g. to be able to trigger properties' observers).
The warning is correct in that the use of defer here doesn't change the order of execution of your program, which is what the statement is designed for. It is however unfortunate that the suggested replacement otherwise changes the behaviour of your program (filed a bug: SR-10207).
It's worth noting that the use of defer to trigger a property observer is a bit of a hack that only works because the type checker considers it to be a different context to the deinit body. You can also achieve the same result with a closure expression:
deinit {
{ foo = bar }()
}
Ideally, there would be some form of syntax that lets you tell Swift "don't perform a direct-to-storage access here", so that such workarounds aren't necessary, but there isn't currently.
A less hacky workaround is to pull out the desired logic of the deinitialiser into a separate method, which puts the logic in a context where property accesses are done normally:
class C {
var bar = ""
var foo: String {
didSet {
// smt
}
}
init(foo: String) { self.foo = foo }
private func doDeinit() {
foo = bar
}
deinit {
doDeinit()
}
}
I have written 2 codes .The functionality of both the code is same.Both the codes take user data then store it in map and on providing keys we get correspoding user data. I have written an extra logic in code2, whic I have mentioned below.
Code1:
class user(var name:String,var id:Int, var gender:Option[String])
{
override def toString="("+ name+","+id+","+gender+")"
}
object a
{
def main(args:Array[String]):Unit={
var a=new user("kl",90,Some("Male"))
println(a.name,a.id,a.gender)//ACESS VALUES
//DEFINING MAP
var mm=Map(1-> new user("jh",189,Some("Male")),2->new user("gh",12,None),3
->new user("io",100,Some("Female")))
// defining method giving o/p value of specific key of mm
def getkey(i:Int)=
{ mm.get(i)
}
var u1=getkey(readLine("ENTER THE KEY").toInt) // some[user]
println(u1.getClass.getName)
if(u1.isDefined)
{
println(u1.get+","+u1.get.name+","+u1.get.id+","+u1.get.gender)
}
}
}
Code1 1 works properly and O/P is right. I have added extra logic in Code2. The extra logic is getKey method. I have written a code for checking whether the input key is present in map. There I am getting an error:
**value get is not a member of java.io.Serializable**_
Code2:
class user(var name:String,var id:Int, var gender:Option[String])
{
override def toString="("+ name+","+id+","+gender+")"
}
object a
{
def main(args:Array[String]):Unit={
var a=new user("kl",90,Some("Male"))
println(a.name,a.id,a.gender)//ACESS VALUES
//DEFINING MAP
var mm=Map(1-> new user("jh",189,Some("Male")),2->new user("gh",12,None),3-> new user("io",100,Some("Female")))
// defining method giving o/p value of specific key of mm
def getkey(i:Int)=
{
//EXTRA LOGIC
var a=(mm.keys).toList
if(a.contains(i)){mm.get(i)}
else {"NO SUCH ELEMENT EXCEPTION , KEY DOESNT MATCH"}
}
print("ENTER THE KEY \n")
var u1=getkey(1) // some[user]
println(u1.get)
}
}
ERROR -
enter code here
eg1.Option.scala:27: error: value get is not a member of
java.io.Serializable
println(u1.get)
^
one error found
Why does the seriliazable errors occurs in Code2 and not in Code1? Is the error due extra logic in Code2? How to fix an error?
Thank you!
It happens because your getKey function return type is io.Serializable.
Reason for this is that every branch of your if expression is returning a different type:
def getkey(i:Int) = { // io.Serializable
//EXTRA LOGIC
var a=(mm.keys).toList
if(a.contains(i)) { mm.get(i) } // option here
else { "NO SUCH ELEMENT EXCEPTION , KEY DOESNT MATCH" } // string here
}
Consider rewriting your function, so its return type is Option[User], one way of doing so is:
def getkey(i:Int): Option[user] = {
//EXTRA LOGIC
var a=(mm.keys).toList
if(a.contains(i)) { mm.get(i) }
else { None }
}
However, there is no need for checking keys, you can simplify this function to:
def getkey(i:Int): Option[user] = {
//EXTRA LOGIC
m.get(i)
}
Hint: write expected return type for functions to see what's going wrong in such cases.
I have some expensive promises that get called in different spots. Ideally, I'd like to just chain off an existing in-flight promise (with an optional force), so I find myself doing something like this:
class Expensive {
var fooPromise : Promise<Foo>?
var barPromise : Promise<Bar>?
func doExpensiveFoo(force: bool = false) -> Promise<Foo> {
if let existing = fooPromise where existing.pending || (existing.fufilled && !force) {
// Return the existing promise
return existing
}
// Start a new Foo
return firstly {
// ...
}
}
func doExpensiveBar(force: bool = false) -> Promise<Bar> {
if let existing = barPromise where existing.pending || (existing.fufilled && !force) {
// Return the existing promise
return existing
}
// Start a new Bar
return firstly {
// ...
}
}
}
But that feels like a fair amount of boiler-plate (a local variable for each promise, and the existing chunk at the start of each function), so I'm wondering if anyone has seen a good pattern for abstracting away the variables and wrapper?
To borrow a term from Python, I'm looking for a decorator that would hide all that. Something like:
class Expensive {
private func startFoo() -> Promise<Foo> {
return firstly {
//..
}
}
public doExpensiveFoo = wrapExpensive(startFoo)
}
Any suggestions, or should I look at rolling my own?
I'm no expert, but this pattern worked for me:
private var fooPromise : Promise<Foo>?
func doExpensiveFoo() -> Promise<Foo> {
if let fooPromise = self.fooPromise, fooPromise.isPending {
// return the pending promise
return fooPromise
}
// reassign a newly created promise
fooPromise = firstly {
// do your thing
...
}
return fooPromise!
}
What I like about this pattern is that the method handles pending state internally, and that the promise automatically re-executes if called after it is finished. This allows callers to be ignorant of the internal mechanism or the state of the promise. Obviously, if you need to caller to be part of the decision, then keep the "force" flag approach.
I do not see any common base of Foo and Bar in your example. But even if they would have one Swift still does not support covariance on generic type parameters. At first you would need to create a common protocol for both types. Maybe this helps you to get on track:
Storing generic objects in Swift Array
I want to write equivalent of this Java code in Scala:
final Object foo;
if (/*...*/) {
foo = /* something */;
} else {
foo = /* something else */;
use(foo);
}
useDifferently(foo);
and I am looking for equivalent in Scala. I can't let the variable uninitialized until first use (neither with val or var), so I am forced to write something like
val foo = if (/*...*/) {
/* something */
} else {
val tmp = /* something else */
use(tmp)
tmp
}
useDifferently(foo)
I find the need for temporary variable rather inelegant. Please show me the elegant way.
There's no way to write Scala code directly analogous to your Java code, but you could make this more elegant by restructuring it to achieve greater separation of concerns. At the moment, the conditional does two things: assign a value to foo and, maybe, perform a side effect. Separating these two concerns will result in code like this:
val conditionIsSatisfied = /*...*/
val foo = if (conditionIsSatisfied) {
/* something */
} else {
/* something else */
}
if (conditionIsSatisfied) {
use(foo)
}
useDifferently(foo)
val foo = if (/*...*/) {
/* something */
} else {
/* something else */ match { case v => use(v); v}
}
useDifferently(foo)
You are actually trying to fit not java code in scala, but imperative way of development into functional. You need to write it like this:
val foo = if (/*...*/) {
/* something */
} else {
use(/* something else */)
}
useDifferently(foo)
And make "use()" return updated foo object.
I am trying to make a function to catch org.openqa.selenium.NoSuchElementException, and here is my implementation in scala:
def doesElementExists() = {
try {
//as long as isDisplayed() returns a boolean value, it means the element exists in the html code
seleniumElement.isDisplayed()
true
} catch {
case element_not_found_exception: org.openqa.selenium.NoSuchElementException => {
false
}
}
}
However, as soon as I check for a nonexistent element, which I expect the function to return a false, it blow off and throw back
org.openqa.selenium.NoSuchElementException,
: Unable to locate element: {"method":"id","selector":"nonexistent-element"};
I am wondering why the catch block did not handle the exception?
IsDisplayed is a property of an element that has already been found. What you are doing is essentially this (C# code):
var element = driver.FindById("nonexistent-element"); //<---This is what throws NoSuchElementException
try
{
var displayed = element.IsDisplayed;
}
catch(NoSuchElementException)
{
}
So to achieve what you want, your doesElementExists function should take in the locator as a parameter, and wrap the try-catch statement around finding the element.