How does Rust call "parent method"? Like this in Javaļ¼
public class parent{
...
public void doSomething(){
System.out.println("Parent method");
}
}
public class child extends parent{
...
public void doSomething(){
super.doSomething();
System.out.println("Child method.");
}
}
In Go, we can simulate it by anonymous fields in struct:
type parent struct{}
func (self *parent) doSomething() {
fmt.Println("parent method")
}
type child struct {
parent
}
func (self *child) doSomething() {
self.parent.doSomething()
fmt.Println("child method")
}
func main() {
var c1 child
c1.doSomething()
}
How to simulate it in Rust? Thanks!
It's not quite the same under the hood, but something like
trait DoThings {
fn do_something(&self);
}
struct Parent;
impl DoThings for Parent {
fn do_something(&self) { println("doing something"); }
}
struct Child {
parent: Parent
}
impl DoThings for Child {
fn do_something(&self) {
self.parent.do_something();
println("child");
}
}
fn main() {
let c = Child { parent: Parent };
c.do_something();
}
There are a few proposals for making parts of this automatic (e.g. if we wanted to just call the parent's method directly, i.e. don't override the method in the child, then currently one has to explicitly call the parent's method oneself).
The point of inheritance is being able to overwrite an inherited method. The samples provided above still deal with delegation and not with inheritance.
Let's have a look at some Go code to illustrate this:
type Base struct {}
func (Base) Magic() { fmt.Print("base magic") }
func (self Base) MoreMagic() {
self.Magic()
}
type Foo struct {
Base
}
func (Foo) Magic() { fmt.Print("foo magic") }
If you run the code above this way
f := new(Foo)
f.Magic()
it will print "foo magic" to the console and not "base magic". However, if we run this code
f := new(Foo)
f.MoreMagic()
it will not print "foo magic" as well, but this time "base magic". This is because of the lack of inheritance and thus not being able to overwrite method Magic (aka dynamic linking). So we are still dealing with delegation.
You can work around this f.ex. as described in the section "Inner Patern" in this article. I don't know exactly about this concerning Rust. At first sight it seems to be the same.
Related
I have a rust program that I am creating that repeatedly runs a function in a thread, which causes a value moved error.
Here's some example code (pretty much the same as mine but simplified to get to the point and with a few names changed around)
use std::{thread}
struct Foo {
bar: bool
}
impl Foo {
fn new() -> Self {
Foo { bar: false };
}
fn do_something2(self) {
// do something
// technically could be simplified here to self.bar = !some_condition, but someone will
// probably complain about it, not really relevant to the issue anyways
if some_condition {
self.bar = false;
}
}
}
fn do_something(mut foo: Foo) {
foo.bar = true;
thread::spawn(|| {
while foo.bar {
foo.do_something2();
}
});
}
fn main() {
let mut foo = Foo::new();
do_something(&mut foo);
// other code
}
I am not sure how I would stop the variable from being moved. In this example, it could technically be avoided by implementing the Copy trait, but my struct has a Vec as one of the values, so I cannot use Copy and need to find a different way.
First you'll want do_something to take a reference rather than an owned value. You can do that like so:
fn do_something(foo: &mut Foo) { ... }
The method Foo::doo_something2 should also be changed to take a mutable reference:
fn do_something2(&mut self) { ... }
Once you do that you'll encounter a new error. thread::spawn has no way to prove that the reference outlives the thread that is being created. Lucky for you there is a new feature in the standard library called "scoped threads" that allows you to prove to the compiler that foo won't be dropped before the child thread terminates.
You can use scoped threads like so:
fn do_something(foo: &mut Foo) {
foo.bar = true;
thread::scope(|scope| {
scope.spawn(|| {
while foo.bar {
foo.do_something2();
}
});
});
}
In javascript we can use the static keyword to define a static method or property for a class. Neither static methods nor static properties can be called on instances of the class. Instead, they're called on the class itself. So, for instance, we could count the number of instances of a certain class we've created:
class Player{
static playerCount = 0;
constructor(){
Player.playerCount ++;
}
}
Is their anything in rust that would roughly equivalent to this? Or possibly a library/macro that allows for something similar?
struct Player{}
impl Player{
static playerCount;
pub fn new()->Self{
playerCount ++
//increment playerCount
}
}
There isn't such a thing as a static field in a Rust struct. Rust's structs are closer to their C namesake than the classes you'd find in object-oriented languages.
The rough equivalent is probably a static mut variable, which requires the use of unsafe code. This is because a globally accessible, mutable value is going to be a source of undefined behavior (such as data races) and Rust wants all code to be free of UB unless you write the word unsafe.
For your use case, perhaps a PlayerManager struct which holds this state and is passed by &mut reference to the new function is a good idea.
struct PlayerManager {
count: usize,
}
impl PlayerManager {
pub fn add_player(&mut self) {
self.count += 1;
}
}
// then...
impl Player {
pub fn new(manager: &mut PlayerManager) -> Self {
manager.add_player();
// TODO: the rest of player construction
}
}
I am a C++ programmer learning Rust, and one of my main use cases is a graph-based computation engine. In my graph I have store a homogeneous type, and then I derive from this with a more specific type e.g. in C++
class BaseNode {
public:
BaseNode(std::vector<std::shared_ptr<BaseNode>>& parents);
virtual ~BaseNode() = default;
virtual void update();
const std::vector<std::shared_ptr<BaseNode>>& parents() const;
...
};
template<typename T>
class TypedNode<T> : public BaseNode {
public:
const T& value() const { return value_; }
...
private:
T value_;
}
The idea is that the graph is traversed and update() is called on each node. The node knows what each of its parents "true type" is and so in its update() can do something like static_cast<TypedNode<DataBlob>>(parents()[0]).
How do I achieve something like this in Rust?
I thought about having a design like this:
trait BaseNode {
fn parents(&self) -> &Vec<dyn BaseNode>;
}
trait TypedNode<T>: BaseNode {
fn value(&self) -> &T;
}
But I read that I won't be able to cast the "trait object" from a BaseNode into a TypedNode<T>. (Or can I do it somehow using unsafe?). The other alternative I thought would be to have a struct that stores the data in Any and then to cast that, but does that incur some runtime cost?
If all node's parents have the same type then you can use that approach:
trait BaseNode {
type Parent: BaseNode;
fn parents(&self) -> &[Self::Parent];
}
trait TypedNode<P: BaseNode>: BaseNode<Parent = P> {
type ValueType;
fn value(&self) -> &Self::ValueType;
}
Rust playground
I'm not sure if I understand your question. Please let me know if it doesn't work for you.
I am starting to play with Rust for a new library. I'm trying to wrap my head around the possible ways to implement the following.
What follows is more of desired expression not real syntax. All of the ways I've tried to express this either don't compile, or don't compile when I go to implement one of the alias traits.
struct ConcreteType;
struct CommonType;
trait Handler<Rin, Rout = Rin>{
fn handle_event(&self, msg: &Rin);
}
// alias Handler with one of the types defined as a common case
trait HandlerToMessage<M> : Handler <ConcreteType, M>{
fn handle_event(&self, msg: &ConcreteType) {
// default implementation of parent trait
// example is simplified, forget about how Rout/M is actually used
self.decode(msg)
}
// method to implement
fn decode(&self, msg: &ConcreteType) -> M;
}
// another alias for most common case where Rin/Rout are ConcreteType, CommonType most often
trait HandlerToCommonType : HandlerToMessage <ConcreteType, CommonType>{
fn decode(&self, msg: &ConcreteType) -> CommonType
{
...
};
}
Alternative using associated types
trait Handler{
type Rin;
type Rout; // not yet able to do Rout = Rin with associated types
fn handle_event(&self, msg: &Self::Rin) -> Self::Rout;
}
trait HandlerToMessage : Handler <Rin=ConcreteType>{
fn handle_event(&self, msg: &Self::Rin) {
// common functionality
self.decode(msg)
}
// method to implement
fn decode(&self, msg: &Self::Rin) -> Self::Rout;
}
trait HandlerToCommonType : HandlerToMessage <Rout=CommonType>{
fn decode(&self, msg: &ConcreteType) -> CommonType
{
...
}
}
In C++ this is roughly what I want to accomplish
// real world example I've seen in the wild of this structure
template <class Rout>
class Context {
public:
void dispatch(Rout* msg);
};
template <class Rin, Rout = Rin>
class ReadHandler {
public:
void read (Context* ctx, Rin* msg) = 0;
private:
Context<Rout> ctx_;
};
// very common to convert from a byte buffer some message type
template <class M>
class BytesToMessageDecoder : ReadHandler<IOBuffer, M> {
public:
// Template method pattern
void read (Context* ctx, IOBuffer* msg) {
M msgOut;
bool success;
success = this->decode(msg, &msgOut);
if (success) {
ctx->dispatch(msgOut);
}
}
bool decode(IOBuffer* msg, M* msgOut) = 0;
}
// convert one byte buffer to another is common
typedef BytesToMessageDecoder<IOBuffer> BytesToBytesDecoder;
// Concrete implementations
// look for fixed number of bytes incoming
class FixedLengthFrameDecoder : BytesToBytesDecoder {
bool decode(IOBuffer* msg, IOBuffer* msgOut) { ... }
}
// fields are prefixed with a length. Wait for that many bytes and then dispatch
class LengthBasedFieldDecoder: BytesToBytesDecoder {
bool decode(IOBuffer* msg, IOBuffer* msgOut) { ... }
}
class StringDecoder : BytesToMessageDecoder<std::string> {
// decode from byte buffer to a string
bool decode(IOBuffer* msg, std::string* msgOut) { ... }
}
Basically the top level trait Handler is the most generic but maybe not meant to be implemented by anyone but advanced library users. The HandlerToMessage trait is meant to be a common conversion where we take ConcreteType and convert to some other type. The library may implement several of these. The HandlerToCommonType is the most common case that numerous library types would want to start from.
The details on how Rout is used in the Handler trait is not of importance. I tried to simplify the example and left off some arguments to hopefully make what I'm trying to convey more concise. All of my searching on this either has me thinking this isn't possible to convey or I am misusing it. I don't quite understand if this falls under the new specialization implementation, it doesn't feel like it from my understanding though.
I realize Rust is not C++ and so maybe what I'm trying to do is either not supported or has a different syntax. Any help is appreciated either in correct syntax or a more idiomatic Rust way.
Perhaps you can just have separate traits and implement one for all implementers of the other:
struct ConcreteType;
struct CommonType;
trait Handler<Input, Output = Input> {
fn handle_event(&self, msg: &Input) -> Output;
}
trait HandlerToMessage<M> {
fn decode(&self, msg: &ConcreteType) -> M;
}
impl<T, M> Handler<ConcreteType, M> for T
where T: HandlerToMessage<M>
{
fn handle_event(&self, msg: &ConcreteType) -> M {
self.decode(msg)
}
}
impl HandlerToMessage<CommonType> for () {
fn decode(&self, _msg: &ConcreteType) -> CommonType {
unimplemented!()
}
}
fn main() {}
The last one is really awkward because you'd normally implement a trait for a concrete type, but you haven't really presented any that make sense to implement for.
I have a struct as follows
type MyStruct {
EmbeddedFooBar
}
func (m *MyStruct) Foo(b *http.Request) {
// Doing something
}
func fn(args ...interfaces) {
// It's here I want to get my struct back and run the "Get" method
// Please keep in mind I am too pass a pointer param into the struct method
strt := args[0]
....
get struct back to static data type MyStruct
and run "Get()", dont mind how/where I will get *http.Request to pass, assume I can
....
strt.Get(*http.Request)
}
func main() {
a := &MyStruct{}
fn(a)
}
I am passing the struct above to a variadic function fn that expects ...interfaces{} (thus any type can satisfy the params)
Inside the function fn I want to get back my struct MyStruct to it's data type and value and run it's method Get that can also accept receivers such as *http.Request
How do I get My Struct back from the interface arg[0] and run the method Get of the struct with the ability of passing a pointer.
What you want is Type Assertion. Solution could something like this:
func fn(args ...interfaces) {
if strt, ok := args[0].(*MyStruct); ok {
// use struct
} else {
// something went wrong
}
// .......
}
It sounds like what you want here is a specific interface, specifically one that has a Get method that accepts a pointer to an http.Request.
For example:
type Getter interface {
Get(*http.Request)
}
func fn(getters ...Getter) {
getter := getters[0]
getter.Get(*http.Request)
}
func main() {
a := &MyStruct{}
fn(a)
}
This allows the compiler to check that the arguments to fn have exactly the methods you need, but it doesn't need to know anything else about the type. Read more about interfaces here.