Is it possible to define implicit casts for classes?
For instance, I have a class Color:
class Color {
public var r: Int;
public var g: Int;
public var b: Int;
public function new(?r: Int = 0, ?g: Int = 0, ?b: Int = 0) {
this.r = r;
this.g = g;
this.b = b;
}
}
If I have a Array<Int> like this:
var myIntegerArray = [255, 0, 255]; // color written in RGB as an array
var c: Color = myIntegerArray; // <= how to make this possible?
trace(c.r);
I tried #:from on a static function in my class:
#:from
static public function fromArray(a: Array<Int>) {
return new Color(a[0], a[1], a[2]);
}
but the compiler is still not happy about this (Error: Array<Int> should be Color).
I know I could just use the static function like var c = Color.fromArray(myIntegerArray); but I'm curious whether or not it is possible to implicitly cast it.
No, implicit cast for normal class is impossible. But you have three solutions:
Create abstract Color(Array<Int>) instead class;
Use "chain" e.g. class Color > abstract ColorAbs > Array<Int>;
Use haxe.extern.EitherType<Color, Array<Int>>;
I don't recommend the second solution.
Related
Suppose there is some struct, with a nested struct that has some functionality I want to modify or extend. How do you override a computed property of a struct, when the computed property is inside a nested struct? Example:
public struct Foo {
var c: Int
init(c: Int) {
self.c = c
}
// Suppose there's lots of implementation
}
extension Foo {
struct FooContent {
var a: Int
public var b: Int { self.a + 1 }
init(a: Int) {
self.a = a
}
}
// Suppose there's lots of implementation
}
var obj = Foo.FooContent(a: 1)
print(obj.b)
Suppose I want to override b to be self.a + 2, and not touch any other functionality in Foo or FooContent. Is there a way to do this something along the lines of
extension Foo.FooContent {
public var b: Int { self.a + 2 }
// won't compile because b is already defined
}
Seems like a big hole in the language design that structs + extension functionality can't be inherited. I figure I'm missing something.
I am new to C++. How do you create a method within one class which initializes an object within another class with specified parameters? Something like the following.
class A {
public:
double X;
double Y;
A(double a, double b) {
X = a;
Y = b;
};
class B {
public:
A f(double a, double b) {
//Initialize an object of type A using parameters specified.
};
};
I want to use the object of type A later so, presumably, I would need to use the new operator within f. Thanks in advance.
Try this:
class B {
public:
A* f(double a, double b) { return new A(a, b); };
};
Although you could just as easily do new A(a,b) anywhere you wanted to do B.f(a,b).
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.
What's difference between final variables and non-final variables :
var someVar = 5
final var someFinalVar = 5
and
let someLet = 5
final let someFinalLet = 5
The final modifier is described in the Swift Language Reference, which says
final
Apply this modifier to a class or to a property, method, or subscript member of a class. It’s applied to a class to indicate that the class can’t be subclassed. It’s applied to a property, method, or subscript of a class to indicate that a class member can’t be overridden in any subclass.
This means without final we can write:
class A {
var x: Int {return 5}
}
class B : A {
override var x: Int {return 3}
}
var b = B()
assert(b.x == 3)
but if we use final in class A
class A {
final var x: Int {return 5}
}
class B : A {
// COMPILER ERROR
override var x: Int {return 3}
}
then this happens:
$ swift final.swift
final.swift:6:18: error: var overrides a 'final' var
override var x: Int {return 3}
^
final.swift:2:15: note: overridden declaration is here
final var x: Int {return 5}
Final variables can't be overridden in subclasses. It also hints this to the compiler which allows it to inline the variable. It other words every time the compiler sees a final variable being used somewhere, it can immediately substitute the value. Whether or not the compiler actually does this is up to the compiler and whatever optimisations it knows/uses.
import Cocoa
public class Ut {
public func foo(m: Int) -> Int {
return m*m
}
}
class ViewController: NSViewController {
let j = 3
let k = Ut.foo(j) // 'ViewController.Type' does not have a member named 'j'
...
Unfortunately, you can’t access other properties when giving properties their initial values:
struct S {
let a = 1
// error: S.Type does not have a member named a
let b = a + 1
}
Instead, you have to initialize these values inside init:
struct S {
let a: Int
let b: Int
init() {
// note, a must be initialized in here
// too if b relies on it
a = 1
b = a + 1
}
}
(also, it looks like you’re using Ut.foo as a class-level function but it’s a member function - but this particular error is about the property init)
You have to make your foo(m: Int) as class function in order to call directly like that. Otherwise, you have to create an instance of Ut then call foo() on to this instance
class func foo(m: Int) -> Int {
return m*m
}
then in other place:
let k = Ut.foo(j)
If you pass j as parameter, this call must be placed inside a function, not at class level. If you want to call at class level, pass a value (like: let k = Ut.foo(5) )