How do I check if a trait is implemented at compile time in Rust? - reflection

I want to print a variable with the Display trait if it is implemented, or with the Debug trait otherwise. All the types are known at compile time.
let display = MyDisplayType::new(); // implements Display
let debug = MyDebugType::new(); // implements Debug
output!(display); // uses Display a.k.a. println!("{}", display);
output!(debug); // uses Debug a.k.a. println!("{:?}", debug);
What is the cleanest way?

It's possible if you want to assert that a type, at compile time, implements a trait. For example in a unit test you can create a function bounded for the trait. If the type doesn't implement the trait, the code will not compile.
fn implements_the_trait<T: MyTrait>() {}
#[test]
fn implements_my_trait() {
implements_the_trait::<MyType>();
}

Related

When and how to use a vector of references

This code correctly compiles. It has a few unused code warnings, but that's okay for now.
use std::collections::BTreeMap;
enum Object<'a> {
Str(String),
Int(i32),
Float(f32),
Vector(Vec<&'a Object<'a>>),
Prim(fn(State) -> State)
}
struct State<'a> {
named: BTreeMap<String, &'a Object<'a>>,
stack: Vec<Object<'a>>
}
impl<'a> State<'a> {
fn push_int(&mut self, x: i32) {
self.stack.push(Object::Int(x));
}
}
fn main() {
println!("Hello, world!");
let obj = Object::Str("this is a test".to_string());
}
The important part of this code is push_int and stack: Vec<Object<'a>>.
I'm sort of trying to make a stack-based VM.
I want to pass the state to functions, which can take stuff off the stack, manipulate the stuff, and then put some stuff back on the stack; the named field is going to hold named objects.
I have a hunch that it would be better to have the stack represented as a Vec<&'a Object<'a>> instead.
The way I have it now, I fear I'm committing some inefficiency error. Is my hunch correct?
The second part of the problem is that I don't know how to get the vector of references version to work. Creating new value with the right lifetimes to push onto the stack is not working for me.
I'm a bit vague about this issue, so if I've been unclear, ask me questions to clear stuff up.
The reason you could not get it to work is that structs cannot have fields that refer to other fields. (See supporting links at the bottom.)
What you can do, is put all the Objects into your Vec, and have the HashMap contain the indices of the named elements it references.
struct State {
named: BTreeMap<String, usize>,
stack: Vec<Object>
}
I'd also remove all lifetimes from your example, as this can be done completely with owned objects.
enum Object {
Str(String),
Int(i32),
Float(f32),
Vector(Vec<Object>),
Prim(fn(State) -> State)
}
You can try out a working implementation in the Playground
Supporting links:
How to initialize struct fields which reference each other
using self in new constructor
How to design a struct when I need to reference to itself
How to store HashMap and its Values iterator in the same struct?
What lifetimes do I use to create Rust structs that reference each other cyclically?
How to store a SqliteConnection and SqliteStatement objects in the same struct in Rust?
Why can't I store a value and a reference to that value in the same struct?
https://stackoverflow.com/questions/33123634/reference-inside-struct-to-object-it-owns

How can I wrap another type and add fields and methods to it?

I know inheritance is a bad word in the Rust world, however there must be some way, given the following struct
struct Glyph {
// Fields
}
to have a new Glyphs struct that is a wrapper for Vec<Glyph> methods (push, etc.) as well as fields and methods proper to itself?
You can use Deref and DerefMut, like so:
use std::ops::{Deref, DerefMut};
struct Glyph;
struct Glyphs(Vec<Glyph>);
impl Glyphs {
fn new() -> Self {
Glyphs(vec![])
}
}
impl Deref for Glyphs {
type Target = Vec<Glyph>;
fn deref(&self) -> &Vec<Glyph> { &self.0 }
}
impl DerefMut for Glyphs {
fn deref_mut(&mut self) -> &mut Vec<Glyph> { &mut self.0 }
}
fn main() {
let mut gs = Glyphs::new();
gs.push(Glyph);
gs.push(Glyph);
println!("gs.len: {}", gs.len());
}
Note that this is not inheritance. A big limitation is that you absolutely cannot prevent someone from calling any of Vec's methods, since they can just manually deref a Glyphs into a Vec<Glyph>. You can "override" methods by defining them on Glyphs, but again, someone can just go behind your back by manually dereferencing a Glyphs.
You may also wish to read the Deref coercions chapter of the Rust Book.
You can define a type alias (i.e. a synonym):
type Glyphs = Vec<Glyph>;
It is not a distinct type, so you can pass a Glyphs to any function that expects a compatible Vec, including generic functions.
You will not be able to add fields or inherent methods to this type directly. What you can do, though, is define an extension trait (i.e. a trait that exists for the sole purpose of adding methods to a type you didn't define; there's no special syntax for this) and have Glyphs implement it. If you use modules, you'll have to import the trait with use to bring the methods into scope.
trait GlyphsExt {
fn x(&self); // define extension method
}
impl GlyphsExt for Glyphs {
fn x(&self) {
// implement method here
}
}
In my opinion, you shouldn't use Deref and DerefMut to emulate some aspects of inheritance. They exist for writing custom pointer types.
When you're writing a wrapper struct like this, you typically only need some of Vecs functionality. There may also be some invariants that need to hold. By implementing Deref and DerefMut you're making your Glyphs harder to reason about and easier to misuse. Avoiding to expose implementation details is generally also preferable.
So the solution would be to implement the functions you need on Glyphs. These are probably only a few. And if you really need all or most of Vecs functions and trait implementations, then a wrapper struct wasn't the right choice to begin with.

Swift discover protocol methods

I'm developing a HTML5 showcase application and I need to discover all the methods in my Swift protocols. All the protocols extends from a base protocol.
The application is a HTML5 showcase for testing this methods. The app calls the method and gives the response.
I found some information about one specific protocol but i need to discover all the protocols in my app and then all the information (name, arguments name arguments type and return values) about this methods.
#objc protocol Protocol {
func method1()
func method2() -> Bool
func method3(param1:Int) -> Bool
func method4(param1:Int, param2:Int, param3:Int) -> Bool
}
var numMethods:UInt32 = 0
var methods:UnsafeMutablePointer<objc_method_description> = protocol_copyMethodDescriptionList(Protocol.self, true, true, &numMethods)
for var iuint:CUnsignedInt = 0; iuint < numMethods; iuint++ {
var i:Int = Int(iuint)
var method:objc_method_description = methods[i]
println("Method #\(i): \(method.name)")
}
I'm using Objective-C Runtime Reference
Any ideas how to do this in swift?
You are going to want to get:
the method implementation (method_getImplementation) https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ObjCRuntimeRef/index.html#//apple_ref/c/func/method_getImplementation
and the method selector (method_getName) https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ObjCRuntimeRef/index.html#//apple_ref/c/func/method_getName
Then in objective-c (using a bridged file, of course), cast the method implementation (i.e. IMP) as a function pointer. Then call the function pointer in objective-c with the
target
selector
and any parameters you may have
id (*func)(id, SEL, id) = (void *)imp;
return func(target, selector, param);`
Take a look at how in this blog post he calls the init method and that should help as well.
http://ijoshsmith.com/2014/06/05/instantiating-classes-by-name-in-swift/
There is no real reflection in swift.
For more reading, please read:
Does Swift support reflection?
How do I print the type or class of a variable in Swift?
http://waffletower.blogspot.sg/2014/06/swift-doesnt-have-much-objective-c.html
https://github.com/mikeash/MAObjCRuntime

How to check if interface specifies method using reflection

I want to reflect to determine whether or not a Go interface contains certain method signatures. I've dynamically got the names and signatures, previously through reflection on a struct. Here's a simplified example:
package main
import "reflect"
func main() {
type Mover interface {
TurnLeft() bool
// TurnRight is missing.
}
// How would I check whether TurnRight() bool is specified in Mover?
reflect.TypeOf(Mover).MethodByName("TurnRight") // would suffice, but
// fails because you can't instantiate an interface
}
http://play.golang.org/p/Uaidml8KMV. Thanks for your help!
You can create a reflect.Type for a type with this trick:
tp := reflect.TypeOf((*Mover)(nil)).Elem()
That is, create a typed nil pointer and then get the type of what it points at.
A simple way to determine if a reflect.Type implements a particular method signature is to use its Implements method with an appropriate interface type. Something like this should do:
type TurnRighter interface {
TurnRight() bool
}
TurnRighterType := reflect.TypeOf((*TurnRighter)(nil)).Elem()
fmt.Println(tp.Implements(TurnRighterType))

Using Recursive References in Go

I want to contain all my commands in a map and map from the command to a function doing the job (just a standard dispatch table). I started with the following code:
package main
import "fmt"
func hello() {
fmt.Print("Hello World!")
}
func list() {
for key, _ := range whatever {
fmt.Print(key)
}
}
var whatever = map[string](func()) {
"hello": hello,
"list": list,
}
However, it fails to compile because there is a recursive reference between the function and the structure. Trying to forward-declare the function fails with an error about re-definition when it is defined, and the map is at top-level. How do you define structures like this and initialize them on top level without having to use an init() function.
I see no good explanation in the language definition.
The forward-reference that exists is for "external" functions and it does not compile when I try to forward-declare the function.
I find no way to forward-declare the variable either.
Update: I'm looking for a solution that do not require you to populate the variable explicitly when you start the program nor in an init() function. Not sure if that is possible at all, but it works in all comparable languages I know of.
Update 2: FigmentEngine suggested an approach that I gave as answer below. It can handle recursive types and also allow static initialization of the map of all commands.
As you might already have found, the Go specifications states (my emphasis):
if the initializer of A depends on B, A will be set after B. Dependency analysis does not depend on the actual values of the items being initialized, only on their appearance in the source. A depends on B if the value of A contains a mention of B, contains a value whose initializer mentions B, or mentions a function that mentions B, recursively. It is an error if such dependencies form a cycle.
So, no, it is not possible to do what you are trying to do. Issue 1817 mentions this problem, and Russ Cox does say that the approach in Go might occasionally be over-restrictive. But it is clear and well defined, and workarounds are available.
So, the way to go around it is still by using init(). Sorry.
Based on the suggestion by FigmentEngine above, it is actually possible to create a statically initialized array of commands. You have, however, to pre-declare a type that you pass to the functions. I give the re-written example below, since it is likely to be useful to others.
Let's call the new type Context. It can contain a circular reference as below.
type Context struct {
commands map[string]func(Context)
}
Once that is done, it is possible to declare the array on top level like this:
var context = Context {
commands: map[string]func(Context) {
"hello": hello,
"list": list,
},
}
Note that it is perfectly OK to refer to functions defined later in the file, so we can now introduce the functions:
func hello(ctx Context) {
fmt.Print("Hello World!")
}
func list(ctx Context) {
for key, _ := range ctx.commands {
fmt.Print(key)
}
}
With that done, we can create a main function that will call each of the functions in the declared context:
func main() {
for key, fn := range context.commands {
fmt.Printf("Calling %q\n", key)
fn(context)
}
}
Just populate the map inside a function before using list(). Like that.
Sry I did not see that you wrote "without init()": that is not possible.

Resources