I am trying to use is operator to compare a variable against a user defined class but my compiler is giving it as an error.
my question is: can we use the 'is' operator to compare only to the in built types or can it be used for comparing with the user defined types as well.
Thanks,
It can be used for user defined types too.
A correct syntax looks like:
var myVar1:MyClass;
var myVar2:OtherClass;
if ( myVar1 is MyClass ) trace("myClass"); // this trace executes.
if ( myVar1 is OtherClass ) trace("true"); // this trace does not execute (if OtherClass does not extend MyClass
Related
I need to implement a solution using generics that implements 3 interfaces, but as far as I can tell, generics in dart only supports 1 upper bound?
I have a model that looks like this:
abstract class Category implements Built<Category, CategoryBuilder>, Identifiable, Mapable {
...
}
The contents of the 3 interfaces is not really relevant, and what I'm trying to do, is construct a class that can process this in generic form.
What I want is something like this:
abstract class BaseDB<T extends Built<T, R> & Identifiable & Mapable, R extends Builder<T, R>> {
process(T entity) {
print(entity.id); // From Identifiable
entity.toMap(); // From Mapable
// ... etc
}
}
I know this is possible in both Typescript and Java, but I'm fairly new at Dart. Anyone know?
This is not possible in Dart. You can only put one bound on a type variable.
The bound of a Dart type variable is used to check which operations you can do on an object of the type parameter type. Example:
String something<T extends num>(T value) {
return value.abs().toString();
}
You are allowed to call abs() on value because we know that all instances of value are numbers, and num has an abs method.
If you can write <T extends Foo & Bar>, then there is no simple type in the Dart type system that can describe objects of type T. Dart does not have intersection types (the intersection type Foo & Bar would be a supertype of all types that are subtypes of both Foo and Bar, and a subtype of both Foo and Bar).
If Foo declares Baz method(), Bar declares Qux method(), and value has type T, what is the type of value.method()?
(It would either be disallowed, or the type would be Baz & Qux). This shows that allowing & in type variable bounds leaks intersection types into the remaining type system, and since Dart does not have intersection types, it also does not have multiple bounds on type variables.
When you declare a class, FooBar, implementing both Foo and Bar, you have the same issue: You need to figure out what method returns. However, the language requires you to write that solution into your class, to find some valid return type for FooBar.method, because otherwise the FooBar class declaration is not valid. It requires a user to find a solution to "find a subclass of both Baz and Qux".
A common question, specifically since Dart 2, is if it is possible to require some or all generic type arguments on some or all types - for example List<int> instead of List or MyType<Foo> instead of MyType.
It's not always clear what the intention is though - i.e. is this a matter of style (you/your team likes to see the types), to prevent bugs (omitting type arguments seems to cause more bugs for you/your team), or as a matter of contract (your library expects a type argument).
For example, on dart-misc, a user writes:
Basically, if I have this:
abstract class Mixin<T> {}
I don't have to specify the type:
// Works class Cls extends Object with Mixin<int> {} // ...also works
class Cls extends Object with Mixin {}
Is there some way to make the second one not allowed?
Strictly speaking, yes, and no.
If you want to enforce that type arguments are always used in your own projects (instead of relying on type inference or defaults), you can use optional linter rules such as always_specify_types. Do note this rule violates the official Dart style guide's recommendation of AVOID redundant type arguments on generic invocations in many cases.
If you want to enforce that generic type arguments are always used when the default would be confusing - such as List implicitly meaning List<dynamic>, no such lint exists yet - though we plan on adding this as a mode of the analyzer: https://github.com/dart-lang/sdk/issues/33119.
Both of the above recommendations will help yourself, but if you are creating a library for others to use, you might be asking if you can require a type argument to use your class. For example, from above:
abstract class Mixin<T> {}
abstract class Class extends Object with Mixin {}
The first thing you could do is add a default bounds to T:
// If T is omitted/not inferred, it defaults to num, not dynamic.
abstract class Mixin<T extends num> {}
If you want to allow anything but want to make it difficult to use your class/mixin when T is dynamic you could choose a different default bound, for example Object, or even better I recommend void:
In practice, I use void to mean “anything and I don’t care about the elements”
abstract class Mixin<T extends void> {
T value;
}
class Class extends Mixin {}
void main() {
var c = Class();
// Compile-time error: 'oops' isn't defined for the class 'void'.
c.value.oops();
}
(You could also use Object for this purpose)
If this is a class under your control, you could add an assertion that prevents the class from being used in a way you don't support or expect. For example:
class AlwaysSpecifyType<T> {
AlwaysSpecifyType() {
assert(T != dynamic);
}
}
Finally, you could write a custom lint or tool to disallow certain generic type arguments from being omitted, but that is likely the most amount of work, and if any of the previous approaches work for you, I'd strongly recommend those!
I have a base class with a field called 'Root'. I am trying to assign a value to it by using the following code inside the do binding
base.Root <- somevar
I am getting the following error
error FS0419: 'base' values may only be used to make direct calls to the base implementations of overridden members
What am I missing? It is a field not property in the base class
Apparently, F# compiler does not allow mutating a field of the base class via base. reference in derived class constructor; and the error message prompts you of valid base. keyword usages.
Nevertheless, you may try a nasty hack, for example by upcasting constructed derived instance as in a snippet below :
type FormulaGrammar() as self =
inherit Grammar()
do
... stuff from your gist here......
(self :> Grammar).Root <- expr
Although after a brief peek into your C# prototype irony.aspx I'd say that similar part of constructor there uses not base Grammar, but derived type ExpressionGrammar for setting the Root field, which upon your code simply translates into self.Root <- expr.
I have an F# class that uses the following to declare, but not initialize class members:
[<DefaultValue>] val mutable myVariable : myType
How can I check in the code whether this value has been initialized? I tried:
x.myVariable = null
but that doesn't seem to work.
From your description, it is a bit hard to say what you are actually trying to achieve - using both uninitialized values and inheritance is generally not the preferred way of doing things in F# (but they are both sometimes necessary for interoperability with .NET), so if you follow this direction, you might not be getting that many advantages from using F#.
Wouldn't the following work for you instead? The idea is that we define a base class that takes the value of the private thing through a constructor:
type Base(myThing : Random) =
member x.MyThing = myThing
And an inherited class can then provide a value, but also access it using a member:
type MySubclass() =
inherit Base(new Random(0))
member x.Next() =
x.MyThing.Next()
public function setAlbumTable(AlbumTable $albumTable)
{
$this->albumTable = $albumTable;
return $this;
}
I am talking about first parameter ( it's not parameter btw) looks like datatype ? what is it ? constant ? I encounter this when trying to develop app in zend framework 2
This is PHP's type hinting. It means that the first parameter to this function - $albumTable - must be an instance of the AlbumTable class or a class that inherits from it.
class Car {}
class BlueCar extends Car {}
function drive_the_car(Car $car) {}
drive_the_car(42); // error, first parameter must be an instance of Car
drive_the_car(new stdClass()); // error
drive_the_car(new Car()); // works
drive_the_car(new BlueCar()); // works
The piece of code you're showing is an example of dependency injection via setter method. The setter is passed an instance of AlbumTable and assignes this instance to a class field.
Your method is passed ONLY ONE parameter: $albumTable.
The AlbumTable before the parameter is a type hint and makes sure that only a instance of AlbumTable or a deriving class can be passed to the setter.
It forces the actual parameter ($albumTable) to be an instance of AlbumTable class. PHP will give a fatal error if anything else is passed to the function.
This is useful so you don't have to check what type of variable/object you received in order to make use of it's functions and properties.