The idea, is that, for example we got type of some object:
val tm = getTypeTag("String here").tpe
//> tm: reflect.runtime.universe.Type = java.lang.String
// for example I got another val or var, of some type:
val tmA: Any = "String here"
//> tmA: Any = String here
How to make tmA.InstanceOf(tm) (it is a mnemonic code)? 'Cause tm it is not a type alias, and we cant make InstanceOf[tm] exactly.
EDITED
there I mean analog function for asIstanceOf, to make a sort of type casting
EDITED2
I'll partly answer my question myself. So if we have TypeTags is is all easy!
def tGet[T](t: TypeTag[T], obj: Any): T = obj.asInstanceOf[T]
It is a harder situation if we only got Type and not the whole TypeTag[T].
You can use a mirror to reflect the instance:
val mirror = runtimeMirror(getClass.getClassLoader)
def isTm(a: Any) = mirror.reflect(a).symbol == tm.typeSymbol
And then:
scala> isTm("String here": Any)
res0: Boolean = true
scala> isTm(List("String here"): Any)
res1: Boolean = false
I don't think I have to tell you what a bad idea this is, though.
You need just to use type attribute of your variable after the variable.
As an example you can write:
val h ="hello"
val b:Any = "hhhh"
val stringB: String = b.asInstanceOf[h.type]
println(stringB)
Related
scala> val blank_line_accumulator = sc.accumulator(0,"Blank Lines")
blank_line_accumulator: org.apache.spark.Accumulator[Int] = 0
val input_file2 = sc.textFile("file:///home/cloudera/input2.txt").foreach{x=>if(x.length()==0)blank_line_accumulator +=1}
input_file2: Unit = ()
scala> input_file2.value :40: error: value value is not a
member of Unit
input_file2.value
This is my problem while accessing the Value.
There is no error for me to access the value it worked like a charm.. may be you are doing some simple mistake somewher else. take fresh spark-shell and try again..
scala> blank_line_accumulator.value
res3: Int = 3
to debug this try below... should give Class[Int] = int
scala> blank_line_accumulator.value.getClass
res4: Class[Int] = int
and try to debug scala> blank_line_accumulator.getClass
should give below...
res6: Class[_ <: org.apache.spark.Accumulator[Int]] = class
org.apache.spark.Accumulator
foreach doesn't return any useful value, which is represented as Unit (which you can see in the type: input_file2: Unit = ()). Unit doesn't have a value, so there's nothing to access. Probably you meant blank_line_accumulator.value as Ram Ghadiyaram's answer shows.
Does exist any native function in scala that does the equivalent this?
def strConvert[T](v: Option[T]): String = {
if (v.isDefined)
v.get.toString
else
""
}
For generic T, you can avoid the if with map -- v.map(_.toString).getOrElse("")
scala> Some(1).fold("")(_.toString)
res0: String = 1
scala> None.fold("")(_.toString)
res1: String = ""
Option is a monad. In FP, when working with monads, you define what you want to happen if the monad contains a state (i.e. a value other than None). Otherwise, you move on.
val ostring: Option[String] = functionThatGetsOptionString()
ostring.map { s =>
functionThatUsesString(s)
}
Within the map function, s will contain the raw string if the Option is Some(String) otherwise it won't execute the inner body if Option is None.
Is there a way to get the Type of a field with scala reflection?
Let's see the standard reflection example:
scala> class C { val x = 2; var y = 3 }
defined class C
scala> val m = ru.runtimeMirror(getClass.getClassLoader)
m: scala.reflect.runtime.universe.Mirror = JavaMirror ...
scala> val im = m.reflect(new C)
im: scala.reflect.runtime.universe.InstanceMirror = instance mirror for C#5f0c8ac1
scala> val fieldX = ru.typeOf[C].declaration(ru.newTermName("x")).asTerm.accessed.asTerm
fieldX: scala.reflect.runtime.universe.TermSymbol = value x
scala> val fmX = im.reflectField(fieldX)
fmX: scala.reflect.runtime.universe.FieldMirror = field mirror for C.x (bound to C#5f0c8ac1)
scala> fmX.get
res0: Any = 2
Is there a way to do something like
val test: Int = fmX.get
That means can I "cast" the result of a reflection get to the actual type of the field? And otherwise: is it possible to do a reflection set from a string? In the example something like
fmx.set("10")
Thanks for hints!
Here's the deal... the type is not known at compile time, so, basically, you have to tell the compiler what the type it's supposed to be. You can do it safely or not, like this:
val test: Int = fmX.get.asInstanceOf[Int]
val test: Int = fmX.get match {
case n: Int => n
case _ => 0 // or however you want to handle the exception
}
Note that, since you declared test to be Int, you have to assign an Int to it. And even if you kept test as Any, at some point you have to pick a type for it, and it is always going to be something static -- as in, in the source code.
The second case just uses pattern matching to ensure you have the right type.
I'm not sure I understand what you mean by the second case.
This works:
scala> def test(name: String = "joe"): Boolean = true
test: (name: String)Boolean
I expected this to work in the same way:
scala> val test: String => Boolean = { (name: String = "joe") => true }
console>:1: error: ')' expected but '=' found.
The boring, correct answer is no, you can't, but actually you kind of can, with the experimental single abstract method (SAM) synthesis in 2.11.
First you need to define your own SAM type with the default value for the apply method's parameter:
trait Func {
def apply(name: String = "joe"): Boolean
}
Now you can use the function literal notation to define a Func (note that you'll need to have started the REPL with -Xexperimental for this step to work):
val f: Func = { (name: String) => name == "joe" }
Or just:
val f: Func = _ == "joe"
And then the usual stuff:
scala> f("joe")
res0: Boolean = true
scala> f("eoj")
res1: Boolean = false
And the punchline:
scala> f()
res2: Boolean = true
It's not exactly the syntax you're asking for, and there are no promises that this will ever leave experimental status, and even if it does, default arguments may not be supported—but I still think it's pretty neat that it works now.
To expand on "The boring, correct answer is no" in Travis Brown's answer:
Functions (i.e. objects of FunctionN[...] type) can't have default arguments in Scala, only methods can. Since anonymous function expressions produce functions (and not methods), they can't have default arguments.
This is bit dirty solution I think, using currying
def testDef(nameDef: String)(name2: String): Boolean = {
val name3 = if ( name2 != "") name2 else nameDef
//use name3 for your logic
true
}
//> testDef: (name: String)(name2: String)Boolean
Curry the testDef method to hold default value as shown below.
var test = test("joe")_ //> test : String => Boolean=function1
test("fun") //"fun" will be used as name3
test("") // "joe" will be used as name3
My code is as follows
import scala.collection.mutable.HashMap
type CrossingInterval = (Date, Date)
val crossingMap = new HashMap[String, CrossingInterval]
val crossingData: String = ...
Firstly why does the following line compile?
val time = crossingMap.getOrElse(crossingData, -1)
I would have thought -1 would have been an invalid value
Secondly how do I do a basic check such as the following
if (value exists in map) {
}
else {
}
In Java I would just check for null values. I'm not sure about the proper way to do it in Scala
Typing your code in the interpreter shows why the first statement compiles:
type Date = String
scala> val time = crossingMap.getOrElse(crossingData, -1)
time: Any = -1
Basically, getOrElse on a Map[A, B] (here B = CrossingDate) accepts a parameter of any type B1 >: B: that means that B1 must be a supertype of B. Here B1 = Any, and -1 is of course a valid value of type Any. In this case you actually want to have a type declaration for time.
For testing whether a key belongs to the map, just call the contains method. An example is below - since Date was not available, I simply defined it as an alias to String.
scala> crossingMap.contains(crossingData)
res13: Boolean = false
scala> crossingMap += "" -> ("", "")
res14: crossingMap.type = Map("" -> ("",""))
//Now "" is a map of the key
scala> crossingMap.contains("")
res15: Boolean = true
If you want to check whether a value is part of the map, the simplest way is to write this code:
crossingMap.values.toSet.contains("")
However, this builds a Set containing all values. EDIT: You can find a better solution for this subproblem in Kipton Barros comment.