I have a Hacklang generic class like this:
class SomeClass<T> {
public function __construct(private T $input) {
}
public function __toString() : string {
return (string)$this->input;
}
}
I do not want to limit the variable that can be used as <T>, but I do want it to be convertible to a string.
Is there a way in Hacklang to specify a given variable should be bool, int, float, string or an object with __toString?
After doing a fair bit of digging, there is no solution to this in Hacklang at the moment. The only thing you have is \Stringish, an undocumented interface that covers both native strings and objects with the __toString method. It does not, however, cover int, float or bool.
Source: interfaces.hhi
Related
This code outputs Null<_Test.Bar_Impl_>. I wanted it to output Foo but I see why it does not work that way. But may be I can somehow overcome this limitation.
My primary goal is to create function that will work like cast, but return null instead of throwing exception. And it should work with abstracts.
class Foo {
}
abstract Bar(Foo) {
}
class MyCast {
inline static public function doCast<T>(value: Any, type: Class<T>): Null<T> {
return Std.is(value, type) ? cast value : null;
}
}
class Test {
static function main() {
$type(MyCast.doCast(null, Bar));
}
}
Actually that cannot work at all like that, since Std.is(value, AbstractType) will always fail because the abstract does not exist any more at runtime.
See https://try.haxe.org/#1Afb5, and especially:
Use #:forward to access foo from Bar instances (forward doc)
Use from Foo to safe cast Foo instances into Bar instances (see implicit cast doc) (note that this feature on itself may be exactly what you were trying to achieve: https://try.haxe.org/#cc903)
I can't seem to get this working, but I'd be surprised if it wasn't possible in Haxe.
I'm trying to pass a couple of Enum values defined in my game to a function, so that it can then concatenate them as String types and pass that to other functions.
Example:
// In a general Entity class:
public override function kill():Void {
messages.dispatchCombined(entityType, ListMessages.KILLED);
super.kill();
}
And in my Messages.hx class:
package common;
import msignal.Signal.Signal1;
/**
* A Message / Event class using Signals bound to String names.
* #author Pierre Chamberlain
*/
class Messages{
var _messages:MessagesDef;
public function new() {
_messages = new MessagesDef();
}
public function add(pType:String, pCallback:FuncDef) {
if (_messages[pType] == null) {
_messages[pType] = new Signal1<Dynamic>();
}
var signals = _messages[pType];
signals.add( pCallback );
}
public function dispatch(pType:String, pArg:Dynamic):Bool {
var signals = _messages[pType];
if (signals == null) return false;
signals.dispatch(pArg);
return true;
}
//Compiler doesn't like passing enums :(
public inline function addCombined(pSource:Enum, pEvent:Enum, pCallback:FuncDef) {
add( combine(pSource, pEvent), pCallback );
}
public inline function dispatchCombined(pSource:Enum, pEvent:Enum, pArg:Dynamic):Bool {
return dispatch( combine(pSource, pEvent), pArg);
}
//How can I just pass the enum "names" as strings?
static inline function combine(a:Enum, b:Enum):String {
return String(a) + ":" + String(b);
}
}
typedef MessagesDef = Map<String, Signal1<Dynamic>>;
typedef FuncDef = Dynamic->Void;
Note how addCombined, dispatchCombined and combine expect an "Enum" type, but in this case I'm not sure if Haxe actually expects the entire Enum "class" to be passed (ie: ListMessages instead of ListMessages.KILLED) or if a value should work. Anyways, compiler doesn't like it - so I'm assuming another special Type has to be used.
Is there another way to go about passing enums and resolving them to strings?
I think you need EnumValue as parameter type (if it is only for enum values), and use Std.String to convert to String values.
static inline function combine(a:EnumValue, b:EnumValue):String {
return Std.string(a) + ":" + Std.string(b);
}
Of course that can be written smaller using String interpolation:
static inline function combine(a:EnumValue, b:EnumValue):String {
return '$a:$b';
}
Of course that can be 'more dynamic' using type parameters:
static inline function combine<A, B>(a:A, b:B):String {
return '$a:$b';
}
There is totally no need to use Dynamic as suggested. If you use Dynamic, you basically turn off the type system.
live example:
http://try.haxe.org/#a8844
Use Dynamic instead of Enum or pass them as Strings right away since you can always convert to enum from String if you need it later.
Anyway pass the enum as enum:Dynamic and then call Std.string(enum);
EDIT: Using EnumValue is definitely better approach than Dynamic, I use Dynamic in these functions because I send more than just Enums there and I am not worried about type safety in that case.
I am new here and this is my first post. I recently got into touch with Jackson and i would like to know if it's possible to get other values than string (or int) while serializing. Pleae be kind if I confuse parts of the terminus.
For example: I have enum
public static enum Type {A, B, C}
in a class like
public class MyClass{
private Type charCat;
public Type getCharCat(){
return this.charCat;
}
public void setCharCat(Type t){
this.charCat = t;
}
}
But if I create an Object (for example with charCat A) and write it into a file I get
...
charCat: "A"
...
How could i get
...
charCat: A
...
?
I tried several tips and solutions, but they did not work.
I am not sure exactly what you are asking for, but the only valid kind of JSON would be
{ "charCat" : "A" }
as all textual values MUST be enclosed in double-quotes. Only values that do not need that are numbers, boolean values (true and false) and null. So serializing value as
{ charCat : A }
would not be valid JSON; so there is no way to get such output.
I know i can do this via Generics, as below, but how do i build an Extension to return the parent type with using Generics?
Generic Extension signature:
public static TEnum FromString<TEnum>(this Enum par , string val ) where TEnum : Enum {
return (TEnum) Enum.Parse(par.GetType(), val);
}
Signature style, i know it wont work but kinda what im looking for.
public static this FromString(this Enum par , string val ) {
return Enum.Parse(par.GetType(), val);
}
basically i have a series of Enum's that are having their values parsed to string for one process and as a receiver i need to parse that string value to the Enum for validation. Ultimately if the string value is not a valid value in the Enumerator it will return a null, or default, value. Its the fact i need to be able to return the source Enumerator's type without having to do a generic.
If its not possible, thats kewl, just figured i would try to do it without generics and do it with the extension logic pattern.
The short answer is no, you need the Generics to return the correct type of the Enum.
Otherwise, you'll just have the basic Enum type and not the specific type of your enum.
What you can do is create an extension method like this:
public static Enum FromString(this Enum par, string val)
{
return (Enum) Enum.Parse(par.GetType(), val);
}
But as you can see, you'll get a type of 'Enum' not of your specific enum.
On the other hand:
Enum val = default(MyEnum).FromString("SomeEnumValue");
bool isEnum = val is MyEnum; // Returns True
As you can see val is of type MyEnum and isEnum returns true
This also works:
MyEnum val = (MyEnum)default(MyEnum).FromString("SomeEnumValue");
I got a class
public class ID_Name<T>
{
public ID_Name(T id)
{
this.ID = id;
}
public T ID { get; set; }
public string Name
{
get
{
return Helper.SomeReturnValue;
}
}
}
All I want to do is generate a custom List of ID_Name where I can pass an ID_Name.ID as parameter in Add.
I tried the following:
public class ID_Name_List<T> : IList<T> where T : ID_Name<T>
but then I get the following error:
The type "EProtokollStatus" cannot be used as type parameter "T" in
the generic type or method "ID_Name_List<\T>". There is no boxing
conversion or type parameter conversion from "EProtokollStatus" in
ID_Name<\EProtokollStatus>.
I read something about this issue here: No boxing or type parameter conversion for generic Type parameter but I can't see a restriction except ID_Name here.
This may be wrong somehow, because everything I want to express is "use the same type T as in ID_Name for ID_Name_List", but how do I achieve that?
I found something here: C#: Declaring and using a list of generic classes with different types, how? but I don't want to create many different classes for all possible types.
All I want to achieve is something like
ID_Name_List<EProtokollStatus> myList = new ID_Name_List<EProtokollStatus>();
myList.Add(EProtokollStatus.ValueX);
Your current constraint makes no sense. Did you mean:
public class ID_Name_List<T> : IList<ID_Name<T>>