How to initialize a field by calling a method - scala

The following class refuses to compile:
class InitTest { // Class 'InitTest' must either be declared abstract
// or implement abstract member 'v: Int'
var v: Int
def int(v : Int) = {
this.v = v
}
}
I was kind of surprise by that we can't just leave values "uninitialized". In Java, it would be assigned with null. In Scala, it does not compile. How to do this in Scala?

You can do this:
class InitTest {
var v: Int = _
def int(v : Int) = {
this.v = v
}
}
Since v has a value type, there is no way of assigning null to it. However, Scala lets you use _ to represent the "zeroed" value. For numbers, that is zero and for pointers that is null. Good way of representing uninitialized values.

Related

How do you define an enum that can only be created by its companion object? (think smart constructors)

I've tried making the constructor private, like this:
enum X {
case Stuff private (value: Int)
}
object X {
def stuff(s: String) =
X.Stuff(performSomeValidationAndCalculation(s))
}
but it complains:
method apply cannot be accessed as a member of Playground.X.Stuff.type from module class X$
I would like to force callers to use the smart constructor to prevent an invalid enum from being instantiated and to limit the number of introduction forms.
Just add the class name to private to limit the scope:
enum X {
case Stuff private[X] (value: Int)
}
object X {
def stuff(s: String) =
X.Stuff(s.toInt)
}
Sample working code: https://scastie.scala-lang.org/hUPECAJFSzqAus6c5slBHQ

kotlin's javaclass.isPrimitive fails if parameter compile-time is not actual type

The following code
fun foo(value:Double) {
if(!value.javaClass.isPrimitive) {
println("try again")
return
}
}
println("that's nice")
}
fun main() {
foo(0.0)
}
displays:
"that's nice"
but setting value type as Any:
fun foo(value:Any) {
if(!value.javaClass.isPrimitive) {
println("try again")
return
}
println("that's nice")
}
fun main() {
foo(0.0)
}
will display: "try again"
even though valueruntime type is Double,
link for testing : https://pl.kotl.in/HkghkAkF4
quote from https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/java-class.html:
inline val T.javaClass: Class
Returns the runtime Java class of this object
which from https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#isPrimitive should give me right
EDIT: removed unnecessary run{}
When you declare the type as Double, that's a primitive double (rather than the Double wrapper class).
When you declare the type as Any, the method then accepts any object as a parameter, so even if you pass in a primitive double, it will be auto-boxed into a wrapper object for Double and will no longer be a primitive.
You can see this by running this snippet on play.kotlinlang.org:
fun main() {
useDouble(3.0)
useAny(3.0)
}
fun useDouble(value: Double) = println("${value.javaClass.name}")
fun useAny(value: Any) = println("${value.javaClass.name}")
Prints:
double
java.lang.Double
isn't there a method like "isPrimitive" for wrapper classes
Not directly, but you can check whether a value belongs to a wrapper class by
value::class.javaPrimitiveType != null
Or if you just have a clazz: Class<T>,
clazz.kotlin.javaPrimitiveType != null

How to pass a class as an function argument in scala?

The problem is the following:
There is a module with such function
def testExceptions(toTest: MyClass): Unit = {
val isException = try {
toTest.increaseValue(-200);
false
} catch {
case e: Exception => true
}
if (isException) {
// some actions
} else {
// another actions
}
}
This function is importing in the file where MyClass is defined. It has such view
class MyClass(var value: Int) {
def show(): Unit = {
println(s"Value: $value")
}
def increaseValue(dv:Int): Unit = {
if(dv <= 0) { throw new IllegalArgumentException }
else { value += dv }
}
}
But I cannot pass MyClass object to the module function testExceptions because it is undefined in the file where this function exists. If I define MyClass in this file, it will be used in the testExceptions.
I will be grateful any help solving my confusion.
How to pass a class as an function argument in scala?
You can't. You can only pass objects as arguments. Classes are not objects, classes are types.
You can use reflection to get a proxy object that represents a type and pass that as an argument, though.
But I cannot pass MyClass object […]
That is because MyClass is not an object, it is a class. You cannot pass a class or any other type as an argument, only objects.
to the module function testExceptions
Note that testExceptions is defined to take an argument that is a value of type MyClass, it does not take MyClass itself as an argument. You need to instantiate an object of MyClass and pass that as an argument.

Swift 2.0 Generics and Type Safety Issues

I was doing this tutorial http://blog.teamtreehouse.com/introduction-learn-power-swift-generics and I came upon this code;
func someFunction<T, U>(a: T, b: U) {}
The problem is when I call the function using
someFunction<String, Int>(1, "Test")
I get an error saying "cannot explicitly specialize a generic function".
I then change it to
someFunction(1,b: "Test")
and now there is no error. The problem is that there is now no type safety. (Is there something wrong with the code, as it was written before swift 2.0?) What is the best way to re-introduce type safety?
The declaration is completely generic and is specifying that any two types can be used.
func someFunction<T, U>(a: T, b: U) {}
It is not that there is no type safety in Swift, this is how you express a generic without any type constraints.
You get what you ask for.
If you wanted to constrain the function to String and Int, you would have written it as
func someFunction(a:String, b:Int)
Generics are more often used with collections, protocols and classes. Basic types rarely need them :
func someFunction<T:Comparable, U:Comparable>(a:T, b:U) -> Bool
{ return (a < b) || (a > b) }
ok, see this 'self explanatory' example. try it in playground and play with it a little bit.
func foo<T>(t: T)->T {
return t
}
// here the resulting type is infered by compiler
let i = foo(1) // 1
let j: Int = foo(1) // 1
let t = foo("alpha") // "alpha"
// if you declare it self ..
//let s: String = foo(1) // error: cannot convert value of type 'Int' to expected argument type 'String'
/* this fails to compile!
func bar<T>(t:T)->Int {
return t.count
}
*/
/* this fails to compile too !!
func bar0<T:CollectionType>(t:T)->Int {
return t.count
}
*/
func bar<T:CollectionType>(t:T)->T.Index.Distance {
return t.count
}
let arr = [1,2,3]
let k:Int = bar(arr) // 3
print(k.dynamicType) // Int
// and even more interesting
let l = bar(arr)
print(l.dynamicType) // Int

Swift - how to declare a method which receives a number in a range

I want to create a function which has a number parameter that should be between 0..100 %
I thought that the best way to enforce this would be by creating a wrapper type using FloatingPointType protocol , but I am getting a compilation error
Protocol 'FloatingPointType' can only be used as a generic constraint because it has Self or associated type requirements
struct Percent {
init(val : FloatingPointType) {
// enforce value is between 0..100
}
}
func hideView(percent : Percent) {
// percent is 0..100 at this point
.. do some work here
}
What would be the correct way to enforce this condition at compile time?
Update: As of Swift 5.1 this can more easily achieved with “property wrappers”, see for example “Implementing a value clamping property wrapper” on NSHipster.
The easiest way would be to define a type that holds a
Double (or Float or Int) in the required range:
struct P {
let val : Double
init (val : Double) {
// ...
}
}
But if you want to treat different floating point types then
you have to define a generic class
struct Percent<T : FloatingPointType> {
let val : T
init(val : T) {
self.val = val
}
}
To compare the values you need to require Equatable as well:
struct Percent<T : FloatingPointType where T: Equatable> {
let val : T
init(val : T) {
if val < T(0) {
self.val = T(0)
} else if val > T(100) {
self.val = T(100)
} else {
self.val = val
}
}
}
Example:
let p = Percent(val: 123.4)
println(p.val) // 100.0
Note that this requires that hideView() is generic as well:
func hideView<T>(percent : Percent<T>) {
// percent.val has the type `T` and is in the range
// T(0) ... T(100)
}
The language feature you are looking for is called Partial Functions. A partial function is a function that is not defined for all possible arguments of the specified type. For instance, they are available in Haskell or Scala - but they are not available in Swift.
So the best you can do is to check at runtime if the provided value lies within the valid range and act accordingly (e.g. raise an exception or return an error).
It sounds like you're trying to enforce, at compile time, that you can't pass a value outside the range 0.0 to 100.0 to a function. You can't do that.
What you can do is write your function to throw an exception if it is passed a value that's out of range, or display an error to the user and return if it's out of range.
Adding up to Martin's answer with updating for Swift 5:
struct Percentage<T: FloatingPoint> {
let value: T
init(value: T) {
self.value = min(max(value, T(0)), T(100))
}
}
Usage site, you can define the generic type like:
func updateCircleWith(percentage: Percentage<CGFloat>) {
// percentage.value will be between 0 and 100 here
// of course the CGFloat(0) and CGFloat(100)
}