I want write method to clear this array, so I choose get every element in array and make this to be null, but compiler says this element must be T, In the document, null is a subtype of every type except of those of value class, and I have defined T extends AnyRef, but it does't work.Is there any way to make this work?
scala version: 2.11.12
class CuckooHashTable[T<: AnyRef: ClassTag](val hashFamily: HashFamily[T]) {
private var data:Array[T] = new Array[T](DEFAULT_TABLE_SIZE)
private val numHashFunctions = hashFamily.getNumberOfFunctions
private var currentSize: Int = _
def this(hashFamily: HashFamily[T], size: Int){
this(hashFamily)
data = new Array[T](size)
}
def doclear = {
for(i <- data.indices){
//error line
data(i) = null
}
}
}
object CuckooHashTable{
private val MAX_LOAD = 0.4
private val ALLOWED_REHASHS = 1
private val DEFAULT_TABLE_SIZE = 101
}
T extends AnyRef, but that does not mean that T is a supertype of Null for every T.
It is not type sound because there is one type in Scala that is not a supertype of Null, which is Nothing. For example, one could do this:
val cht = new CuckooHashTable[Nothing](new HashFamily[Nothing])
Since Nothing is the bottom type in Scala (the subtype of every other type), and Null is not a subtype of Nothing, this is not type sound.
A workaround would be to have Null as the lower bound of type T:
class CuckooHashTable[T >: Null <: AnyRef: ClassTag](val hashFamily: HashFamily[T])
Now Nothing is not allowed anymore, the code becomes type sound, and your code compiles.
Related
Kotlin compiler is giving me error while running below :
fun main() {
val x = object {
val i = 1
val k = "s"
}
val y = x as Planet
if (y is Planet) {
println("Hello " + x.i)
}
}
data class Planet(
var i : Int,
var k : String
)
Error :
Exception in thread "main" java.lang.ClassCastException:
FileKt$main$x$1 cannot be cast to Planet at FileKt.main (File.kt:7)
at FileKt.main (File.kt:-1) at
sun.reflect.NativeMethodAccessorImpl.invoke0
(NativeMethodAccessorImpl.java:-2)
I am unable to understand why i am not able to cast Any object type to specific class object.
Isn't all Kotlin classes inherit from Any super class?
please let me know what i am doing wrong here.
Kotlin is a strongly statically typed language. Every variable and every expression has a type that is known at compile time.
In your example you are not specifying the type, but that does not mean it is unknown at compile time.
Kotlin uses type inference to determine its type. In your case Any.
val x: Any = object {
// ...
}
Any is the root of the Kotlin class hierarchy. Every Kotlin class has Any as a superclass.
This is the reason why you can not cast Any to Planet at runtime.
What you could do is using Kotlin safe-cast as? which returns null instead of an exception:
val planet: Planet? = x as? Planet
What you also can do, if you ever casted a Planet to Any, you can cast it back to Planet.
data class Planet(val name: String)
val pluto: Planet = Planet("Pluto")
val anyPlanet: Any = pluto
val planet: Planet = anyPlanet as Pluto
Thanks to Selvins comments for pointing me to right direction, the problem with my implementation is that i am trying to convert an object to type that is not Planet.
But the problem is that i needed to implement some way to screen the incoming object that is supposed to be of type Planet.
So below is the new implementation where i am checking for property of Planet against the anonymous object, if i get object with any fields other than what is present in Planet it will do nothing.
fun main() {
val x = object {
val i = 1
val k = "s"
}
val i = Planet::class.java.declaredFields.asIterable()
val j = x.javaClass.declaredFields.asIterable()
val b = i.zip(j).all { (f, a) -> f.name == a.name }
if (b){
x.let {
val p = Planet(i=it.i,k=it.k)
Log.d("TAG","$p")
}
}
}
data class Planet( val i: Int, val k: String)
May be not the best way, but feel free to comment.
I'm learning Scala coming from a Java background, and the first thing I've found that works significantly differently than Java are the Enums. I've managed to accomplish everything I've wanted to just by trial and error, but I'd love to better understand what I'm doing along the way.
From the Scala documentation, I'm told to create an enum by extending the class Enumeration, and add values by setting them equal to a constant Value, eg:
object Label extends Enumeration{
val NONE = Value
}
This works about as expected. My trouble comes in using not only enums but extensions of custom written enum extensions. I wrote a chunk of code as part of a Machine Learning class (now over) to separate data by their labels (for use in TDIDT, for example). At the bottom is a small piece of it to get at where I'm confused. The Data object is runnable, just to try it out.
First, on the print statement, I thought it would be true, but it is not
println(Label.NONE.equals(MessageLabel.NONE))//Thought this would be true, is false
Why is this the case? Is that even though the NONE that MessageLabel has inherited is directly from Label, the type system insists that they are different enum values?
Secondly and more importantly I've been going back and forth between Label.Value and Label#Value basically willy-nilly. The version that I posted with:
def splitByLabel[T <: Label#Value]
trait Labelable[T <: Label#Value]
abstract class Data[T <: Label#Value]
class Message( ... val label : MessageLabel.Value)
Compiles and runs correctly. When I change all the #s to ., I get a compile time error on the line splitByLabel(messages).foreach(a => println(a)), stating:
Inferred type arguments [MessageLabel.Value] do not conform to method splitByLabel's type parameter bounds[T <: Label.Value]
But when I change all the .s to #s, I get a compile time error on the line class Message(val index : Int, val s : Map[Double, Int], override val label : MessageLabel#Value) extends Data[MessageLabel#Value](label), stating:
Not Found: Type MessageLabel
So clearly there is a difference between the two and they each fill a specific role. Can someone help me understand what the difference is? Thank you!
/** Enum type all labels should extend. Guarantees access of universal NONE label */
class Label extends Enumeration{
val NONE = Value
}
/** Singleton instance for accessing NONE */
object Label extends Label{}
/** Companion object to all data classes. Hosts helper methods and a runnable main method */
object Data{
/** Returns a map of lists, each list is similarly labeled data. Map is label -> list of data */
def splitByLabel[T <: Label#Value](elms : List[Labelable[T]]) : Map[T, List[Labelable[T]]] = {
def f(acc : Map[T, List[Labelable[T]]], e : Labelable[T]) : Map[T, List[Labelable[T]]] = {
if(acc.contains(e.label)){
val l = acc(e.label)
acc - e.label + ((e.label, (e :: l)))
} else{
acc + ((e.label, List(e)))
}
}
elms.foldLeft(Map[T, List[Labelable[T]]]())(f)
}
def main(args : Array[String]){
println(Label.NONE.equals(MessageLabel.NONE))
val messages : List[Message] = (0 to 10).toList.map(a =>
new Message(a, Map(), if(a % 3 == 0) MessageLabel.HAM else MessageLabel.SPAM))
splitByLabel(messages).foreach(a => println(a))
}
}
/** Implementing classes can be labeled */
trait Labelable[T <: Label#Value]{
/** Returns the label of this thing */
val label : T
/** The possible labelings for this thing */
val labels : List[T]
}
abstract class Data[T <: Label#Value](override val label : T) extends Labelable[T]{
override def toString(): String = {
if (label != null)
label.toString
else
"NO_LABEL"
}
}
object MessageLabel extends Label{
val HAM, SPAM = Value
}
/** An instance represents a sentence. */
class Message(val index : Int, val s : Map[Int, Double], override val label : MessageLabel.Value)
extends Data[MessageLabel.Value](label){
/** Returns the possible labelings for a message */
override val labels = MessageLabel.values.toList
/** Adds index to tostring at front */
override def toString() : String = {
index + "-" + super.toString
}
}
Label#Value is the type Value in the type Label. Label.Value is the type Value in the value Label. (It's a bit confusing because you have both class Label and object Label (i.e. a value)). So a MessageLabel.Value is a Label#Value, because MessageLabel is an instance of the type (class) Label. But it isn't a Label.Value, because MessageLabel isn't the value (object) Label. And there is no MessageLabel#Value because there is no class MessageLabel (or trait).
(FWIW I find scala Enumeration very confusing and prefer to use Java enums in my Scala code)
This is not particular to Enumeration.
scala> class A { class B ; val None = new B }
defined class A
scala> class C extends A ; class D extends A
defined class C
defined class D
scala> val c = new C ; val d = new D
c: C = C#45fe3ee3
d: D = D#4cdf35a9
scala> c.None == d.None
res0: Boolean = false
No one would ever expect that to be true. One value is initialized in one (super-) constructor, another in the other.
Also, Value is not a constant; it's a function that says, "Give me another Value." So you're generating a value for each instance.
In Java, you can't extend enums in this sense. To "extend" is to add members or increase the extension, but subclassing means a subset or restricted domain.
This is a case where one prefers composition over inheritance. Given a set of weekdays and of weekend days, I get alldays by adding them, not by extending weekdays with the weekend.
Here is an example of using an Enumeration in a path-dependent way.
Another issue with the code as it stands:
scala> MessageLabel.NONE
res4: MessageLabel.Value = <Invalid enum: no field for #0>
https://issues.scala-lang.org/browse/SI-5147
I'm trying to write a convenience function that replaces the left tree of an immutable binary tree, and I'm getting "Error occurred in an application involving default arguments" in the following replaceL method:
abstract class AbNode {
val key = null
val value = null
val leftTree:AbNode = NullNode
val rightTree:AbNode = NullNode
}
case class Node[K <:Ordered[K],V](k:K, v:V, lT:AbNode, rT:AbNode) extends AbNode {
val key:K = k
val value:V = v
val leftTree:AbNode = lT
val rightTree:AbNode = rT
}
object Node {
def replaceL[K <: Ordered[K],V](newTree:AbNode, node:Node[K,V]): Node[K,V] =
node.copy(leftTree = newTree) //<< Error occurs here
}
case object NullNode extends AbNode {
val key = null
val value = null
val leftTree = NullNode
val rightTree = NullNode
}
The copy method (and default parameters in general) use the name used in the constructor, not the field name that you assign it to (I don't know why this didn't click sooner).
In the case of a case class, the assigned fields are useless; as far as I can tell, they're simply holding a copy of a reference to the constructor value (not my original intent). I think my confusion stemmed from the fact that in C-style languages, the variables given to a constructor are later assigned to a field. In other words, the way I have my classes set-up is non-sensical, they shouldn't have any fields.
My Node class should be simply:
case class Node[K <:Ordered[K],V](k:K, v:V, leftTree:AbNode, rightTree:AbNode) extends AbNode
Which allows copy to see the value I'm referring to.
Search results so far have led me to believe this is impossible without either a non-primary constructor
class Foo { // NOT OK: 2 extra lines--doesn't leverage Scala's conciseness
private var _x = 0
def this(x: Int) { this(); _x = x }
def x = _x
}
val f = new Foo(x = 123) // OK: named parameter is 'x'
or sacrificing the name of the parameter in the primary constructor (making calls using named parameters ugly)
class Foo(private var _x: Int) { // OK: concise
def x = _x
}
val f = new Foo(_x = 123) // NOT OK: named parameter should be 'x' not '_x'
ideally, one could do something like this:
class Foo(private var x: Int) { // OK: concise
// make just the getter public
public x
}
val f = new Foo(x = 123) // OK: named parameter is 'x'
I know named parameters are a new thing in the Java world, so it's probably not that important to most, but coming from a language where named parameters are more popular (Python), this issue immediately pops up.
So my question is: is this possible? (probably not), and if not, why is such an (in my opinion) important use case left uncovered by the language design? By that, I mean that the code either has to sacrifice clean naming or concise definitions, which is a hallmark of Scala.
P.S. Consider the case where a public field needs suddenly to be made private, while keeping the getter public, in which case the developer has to change 1 line and add 3 lines to achieve the effect while keeping the interface identical:
class Foo(var x: Int) {} // no boilerplate
->
class Foo { // lots of boilerplate
private var _x: Int = 0
def this(x: Int) { this(); _x = x }
def x = _x
}
Whether this is indeed a design flaw is rather debatable. One would consider that complicating the syntax to allow this particular use case is not worthwhile.
Also, Scala is after all a predominantly functional language, so the presence of vars in your program should not be that frequent, again raising the question if this particular use case needs to be handled in a special way.
However, it seems that a simple solution to your problem would be to use an apply method in the companion object:
class Foo private(private var _x: Int) {
def x = _x
}
object Foo {
def apply(x: Int): Foo = new Foo(x)
}
Usage:
val f = Foo(x = 3)
println(f.x)
LATER EDIT:
Here is a solution similar to what you originally requested, but that changes the naming a bit:
class Foo(initialX: Int) {
private var _x = initialX
def x = _x
}
Usage:
val f = new Foo(initialX = 3)
The concept you are trying to express, which is an object whose state is mutable from within the object and yet immutable from the perspective of other objects ... that would probably be expressed as an Akka actor within the context of an actor system. Outside the context of an actor system, it would seem to be a Java conception of what it means to be an object, transplanted to Scala.
import akka.actor.Actor
class Foo(var x: Int) extends Actor {
import Foo._
def receive = {
case WhatIsX => sender ! x
}
}
object Foo {
object WhatIsX
}
Not sure about earlier versions, but In Scala 3 it can easily be implemented like follows:
// class with no argument constructor
class Foo {
// prive field
private var _x: Int = 0
// public getter
def x: Int = _x
// public setter
def x_=(newValue: Int): Unit =
_x = newValue
//auxiliary constructor
def this(value: Int) =
this()
_x = value
}
Note
Any definition within the primary constructor makes the definition public, unless you prepend it with private modifier
Append _= after a method name with Unit return type to make it a setter
Prepending a constructor parameter neither with val nor with var, makes it private
Then it follows:
val noArgFoo = Foo() // no argument case
println(noArgFoo.x) // the public getter prints 0
val withArgFoo = Foo(5) // with argument case
println(withArgFoo.x) // the public getter prints 5
noArgFoo.x = 100 // use the public setter to update x value
println(noArgFoo.x) // the public getter prints 100
withArgFoo.x = 1000 // use the public setter to update x value
println(withArgFoo.x) // the public getter prints 1000
This solution is exactly what you asked; in a principled way and without any ad hoc workaround e.g. using companion objects and the apply method.
I have a feeling that the problem I am facing has something to do with Type Erasure of Scala, but as a newbie I can't put my fingers on it. Need some help here.
First, the code:
class C (val i: Int) {
def mkString() = { println("C.i =" + this.i) }
object C {
implicit val cOrdering = new Ordering [C]
{
def compare (a: C, b: C)=
{
a.i compare b.i;
}
}
Then, I create another class which holds a collection of class 'C' thus:
class ContainerOfC [C] (s:Int) (implicit ordering: cOrdering[C]) {
var internalCollection = new TreeSet[C]()
def + (c:C): ContainerOfC [C] = {
this.internalCollection += c
this
}
def mkStringOfElems () = {
val y = this.internalCollection.toList
println (y.head.i) // <--- Problem here
}
}
This is what REPL tells me:
error: value i is not a member of type parameter C
println(y.head.i)
^
I have checked the type of 'y' out there: it is a List[C]. If so, why am I not allowed to access the 'i'? It is a construction parameter alright, but it is a val and hence, can be treated as a member variable, can't it be?
I have gone through a few of the other related posts in the forum, and Manifests and Typetags are possible ways out here. But, I am not sure if I need to go to that level for this simple use-case.
This have a strange and familiar feeling of "been there, done that".
How about you try to change this:
class ContainerOfC [C] (s:Int) (implicit ordering: cOrdering[C]) { ... }
to this without the type parameter C in the declaration :
class ContainerOfC(s:Int) (implicit ordering: cOrdering[C]) { ... }
The code you showed created a class and specific type C. When you later write class ContainerOfC[C], that C is a type parameter that could be named by any other identifier. It is the same as defining class ContainerOfC[A] where A does not have any relation to the class/type C defined in the earlier code. In your example the type parameter C would shadow the name of the class defined earlier... The error message is indicating that C does not have a value i and that's because the compiler is not referring to the same C than you are thinking of.
Edit: just so you know quickly if we are on the same page without getting bogged down in other compilation errors, here are a few edits to make the code compile and using more commonly used indentation and brace style:
class C(val i: Int) {
def mkString() = println("C.i =" + this.i)
}
object C {
implicit val cOrdering = new Ordering[C] {
def compare(a: C, b: C) = a.i compare b.i
}
}
class ContainerOfC(s: Int)(implicit ordering: Ordering[C]) {
var internalCollection = new collection.mutable.TreeSet[C]()
def +(c: C): ContainerOfC = {
this.internalCollection += c
this
}
def mkStringOfElems() = {
val y = this.internalCollection.toList
println(y.head.i)
}
}