SoFunction
Updated on 2025-05-13

Rust Methods of casting and dynamic pointer type conversion

The coercion semantics in Rust have some similarities with the subclass to parent class conversion in Java or C++, but the implementation mechanisms and usage scenarios of the two are very different.

We willJava/C++ subclass to parent class conversionandRust's castComparing perspectives from the perspectives will help you better understand their similarities and differences.

1. Conversion from subclasses to parent classes in Java and C++

In Java and C++, the conversion from subclass to parent class isinheritDirect result of the relationship.

Java Example

class Parent {
    public void sayHello() {
        ("Hello from Parent");
    }
}
class Child extends Parent {
    public void sayHello() {
        ("Hello from Child");
    }
}
public class Main {
    public static void main(String[] args) {
        Child child = new Child();
        Parent parent = child; // Implicit conversion from subclass to parent class        ();     // Dynamic binding, calling subclass methods    }
}

C++ Example

#include <iostream>
using namespace std;
class Parent {
public:
    virtual void sayHello() {
        cout << "Hello from Parent" << endl;
    }
};
class Child : public Parent {
public:
    void sayHello() override {
        cout << "Hello from Child" << endl;
    }
};
int main() {
    Child child;
    Parent* parent = &child; // Implicit conversion from subclass to parent class    parent->sayHello();      // Dynamic binding, calling subclass methods    return 0;
}

Characteristics Analysis

  • Convert type: The conversion from subclass to parent class is based on inheritance relationship.
  • Dynamic binding
    • When the parent class's method is declared asvirtualWhen (in C++) or when the default dynamic binding (in Java), the implementation of the subclass is called.
    • This means that the parent class reference or pointer can dynamically call the subclass's methods at runtime.
  • Automatic conversion: The conversion from a subclass to a parent class is implicit because a subclass is an extension of the parent class.
  • Direction limit: The parent class cannot be implicitly converted to a subclass (cass required), because the parent class instance may not have subclass-specific members.

2. Rust's coercion

In Rust, casting is not based on inheritance, because Rust does not support traditional inheritance mechanisms. Rust's casting focuses more onSecurity of ownership and borrowing, and type ofcompatibility

The most common scenarios for casting in Rust are:

  • Dereference cast: By implementingDeref/DerefMutCast one type to another.
  • Subtype to supertype conversion:for example&mut Tarrive&T
  • Pointer type conversion for specific scenarios: For exampleBox<T>Cast toBox<dyn Trait>

Example 1: Dereference cast

In RustDerefandDerefMutIt can be used to implement a conversion similar to a subclass to a parent class. Here is an example similar to Java/C++:

use std::ops::Deref;
struct Parent;
impl Parent {
    fn say_hello(&amp;self) {
        println!("Hello from Parent");
    }
}
struct Child;
impl Deref for Child {
    type Target = Parent;
    fn deref(&amp;self) -&gt; &amp;Self::Target {
        &amp;Parent
    }
}
fn main() {
    let child = Child;
    // Dereference cast, automatically call Deref, convert &Child to &Parent    child.say_hello(); // Equivalent to (*child).say_hello()}

By implementingDeref,typeTCan beStatic castforTargettypeU. This mechanism isStatic binding, the method call has been decided at compile time.

Characteristics Analysis

  • Convert type: The conversion in Rust is not based on inheritance, but onDeref
  • Static binding: Rust YesStatic bindingThe method of the call is determined at compile time. ifsay_helloexistParentandChildAll exist in it, Rust will not be selected dynamically, but will be based on call path resolution (i.e.ParentThe method will be called).
  • Manual control: Rust does not support implicit inheritance, so it needs to be implementedDerefManually control the conversion logic.

Example 2: Subtype to supertype conversion (e.g.&mut Tarrive&T

Subtype to supertype conversion in Rust does not depend onDeref, but the language built-in rules, such as&mut TCan be automatically converted to&T

fn take_ref(data: &amp;str) {
    println!("Taking a reference: {}", data);
}
fn main() {
    let mut s = String::from("Hello, Rust!");
    take_ref(&amp;s); // Automatically convert &String to &str}

Characteristics Analysis

  • Convert type&StringBeing cast to&str
  • Static strong type: Rust verifies the security of type conversion at compile time to ensure that there are no violations of ownership rules.

Example 3: Conversion of dynamic pointer types

Dynamic pointers in Rust (e.g.Box<T>) can be cast to a feature object (Box<dyn Trait>), similar to converting a subclass pointer to a parent class pointer:

trait Parent {
    fn say_hello(&amp;self);
}
struct Child;
impl Parent for Child {
    fn say_hello(&amp;self) {
        println!("Hello from Child");
    }
}
fn main() {
    let child = Box::new(Child) as Box&lt;dyn Parent&gt;; // Cast to feature object    child.say_hello(); // Dynamic call to Child implementation}

By typing typeChildConvert to implementation specificTraitFeature Objectsdyn Parent, we can dynamically call methods that implement this feature. This mechanism isDynamic binding, the method call is determined by the runtime.

Characteristics Analysis

  • Dynamic distribution: WhenBox<Child>Convert toBox<dyn Parent>When Rust introduces dynamic distribution for feature objects, similar to Java/C++ dynamic binding.
  • Explicit conversion: This conversion needs to be performed explicitly and is not automatically completed.

The difference between 1 and 3

characteristic Example 1:DerefDereference cast Example 3: Dynamic distribution of feature objects
Purpose TypeTTreat as a type staticallyU TypeTImplementation as an interface
Conversion mechanism By implementingDeref, static binding TypeTConvert todyn Trait, dynamic binding
Call time Compile timeDecide method call RuntimeDecide method call
Is trait required? No features required Must rely on features
Polymorphism There is no polymorphism, all calls are statically determined Supports polymorphism, and can be called through one interface to multiple implementations
Difficulty to achieve Simple, just implementDeref A little complex, it is necessary to define features and implement dynamic distribution mechanisms
performance High efficiency, static distribution, no runtime overhead Slightly lower, dynamic distribution has runtime overhead

Example 1 (Deref dereference cast)

  • Suitable for static conversion between two types.
  • For example, represent Child as Parent and decide to call Parent's method at compile time.
  • Use scenarios:
  • Encapsulation types, such as smart pointers Box<T> and Rc<T>, use Deref to dereference itself as T.
    • Simple type conversions that do not require dynamic behavior.
    • Lack of flexibility, calling a target type method, and cannot achieve polymorphic behavior.
    • Suitable for conversion between two fixed types, or encapsulation types.
  • Example 3 (dynamic distribution of feature objects):
    • It is suitable for interface abstraction, allowing different types to implement the same interface, and multiple implementations are called through unified interfaces.
    • For example, Child implements the Parent feature, allowing it to be called dynamically as a dyn Parent type.
    • Use scenarios:
    • Interface-oriented programming: For example, different types implement the same features, you can manage them with a feature object.
    • When dynamic distribution is required, for example, select specific method calls based on different implementation types at runtime.
    • It has higher flexibility and supports polymorphic behavior, and can be dynamically selected to implement it at runtime.
    • Suitable for scenarios where abstract interfaces or dynamic behavior are required. -

- Comparison of Java/C++ and Rust conversions

characteristic Java/C++ subclass to parent class conversion Rust cast type conversion
Whether to support inheritance Based on inheritance Traditional inheritance is not supported, but features are supported (trait)
Dynamic distribution Support dynamic distribution Feature Object (dyn Trait) Support dynamic distribution
Static distribution Static distribution requires explicit call to the parent class method Default static distribution, method calls are determined at compile time
Automatic conversion Implicit conversion of subclass to parent class Need to be implemented manuallyDerefor specific rules support
Runtime security Supports runtime type checking Strongly typed verification at compile time
Dependence on inheritance relationships Inheritance relationship of dependency classes Not dependent on inheritance, through features orDerefaccomplish

Summarize

Rust's cast has some similarity to Java/C++'s subclass to parent class conversion, but it does not depend on inheritance.

  • Inherited subclass-to-parent conversion in Java/C++ is part of language design and is usually implicit.
  • Rust has no inheritance, through implementationDerefOr explicitly use feature objects to convert type.

Dynamic distribution scenarios

  • In Java/C++, the conversion from subclass to parent supports dynamic distribution and calls the methods of subclass rewrite.
  • In Rust, the feature object (dyn Trait) can achieve dynamic distribution, but requires explicit conversion.

Static binding and type safety

  • Rust prefers static binding and type safety to avoid type errors at runtime.
  • Java/C++ provides certain dynamic behaviors (such asinstanceofordynamic_cast), but may cause runtime errors.

💡 Rust's type system prefers static analysis through features andDerefImplement flexible type conversions, avoiding the complexity that inheritance may bring.

This is the article about Rust cast type conversion and dynamic pointer type conversion methods. For more related rust cast type conversion content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!