对照JAVA学习Rust(07)--类和结构体

10 篇文章 1 订阅

1、Java类和Rust结构体

     对象体结构,Java的类定义可包括属性和函数,或常量。而Rust 结构体里只有属性字段,函数需要在关联到架构体使用impl 结构体名如以下例子。

JavaRust
public class Rectangle{
   public int width;
   public int height,
   public int area(){
     return this.width* this.height;
   }
}
struct Rectangle {
    width: u32,
    height: u32,
}
   
impl Rectangle { fn area(&self) -> u32 {
        self.width * self.height
    }
} 

default (即默认,什么也不写): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。

private : 在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类)

public : 对所有类可见。使用对象:类、接口、变量、方法

protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)

Rust 中有两种简单的访问权:公共(pub)

私有(即默认,什么也不写)。

2、对象内的方法和函数

在Rust的定义绑定的函数和方法,区别是带&self 参数,如下showlog函数和show的方法的区别:

pub struct NetUtils{
    uid:u64
}
impl NetUtils{
    pub fn new() -> NetUtils {
        return NetUtils {uid:100};
    }
    pub fn showLog(&self,name:String){
        println!("{} = {}",name,self.uid);
    }

    pub fn show( name:String){
        println!("{} ",name);
    }
}

对照Java的规范,Rust 通过&self 可使用对象字段,类似Java的this.属性。

3、构造函数

JavaRust

(1)子类只调用父类的默认(缺省)构造函数,即无形参构造函数。如果父类没有默认构造函数,那子类不能从父类调用默认构造函数。

(2)子类从父类处调用默认构造函数,不能成为子类的默认构造函数。

(3)在创建对象时,先调用父类默认构造函数对对象进行初始化,然后调用子类自身自己定义的构造函数。

(4)如果子类想调用父类的非默认构造函数,则必须使用super来实现。

(5)子类必须调用父类的构造函数。可以通过系统自动调用父类的默认构造函数,如果父类没有默认构造函数时,子类构造函数必须通过super调用父类的构造函数。

Rust不存在构造函数,但可以在结构体新增一个或多个方法在该结构体里创建结构体的对象。如

pub struct NetUtils{

uid:u64

}

impl NetUtils{

pub fn new() -> NetUtils {

     return NetUtils {uid:100};

}

pub fn new2(uid_value:u64) -> NetUtils {

    return NetUtils {uid:uid_value};

}

}

4、函数重载

Java 函数重载是在同一个类中,允许存在一个以上的同名函数,只要他们的参数个数或者参数类型不同即可。重载的特点是与返回型无关,只看参数列表。

Rust 不支持重载,但可以通过其他特性实现类似能力。如:1、泛型函数;2、泛型函数需要函数体中用到的泛型类型需要具有共同的方法,因此需要定义必要的 trait。我写了个例子,左值自动推断代码如下:

trait MakeValue<T> {
    fn make_value() -> T;
}

impl MakeValue<i32> for i32 {
    fn make_value() -> i32 {
        123
    }
}

impl MakeValue<String> for String {
    fn make_value() -> String {
        "123".into()
    }
}

fn foo<T: MakeValue<T>>() -> T {
    T::make_value()
}

fn main() {
    let x: i32 = foo();
    println!("{:?}", x);
    let x: String = foo();
    println!("{:?}", x);
}

5、继承

Java 通过externs 关键词,实现继承父类。Rust实现继承目前找到两种方式 ,一种使用AsRef trait,一种使用Deref trait,都能实现单继承,而AsRef则能实现类似多继承的功能。

6、函数重写

Rust不支持对父结构体的继承,只能实现trail的函数。

7、对象释放

Rust 区别与Java/C++等高级语言的重要特征,在于其内存管理的两个特点:

(1)变量超出作用域会自动释放。对于简单值类型的栈内存(如int,struct)超出作用域后自动释放。而对于 new 出来的堆内存,在c/c++中是要手动释放的,在java要委托垃圾回收释放。而垃圾回收不是实时的,会影响性能。而 Rust 对栈内存和堆内存一视同仁,超出作用域一律自动释放。Rust 的这个特点在兼顾性能的情况下、有效的减少了代码量和内存泄漏隐患。

(2) “所有权” :某段内存只能被最后的变量名所有,前面声明过的变量都作废,这有效的避免被多个变量释放的问题,而且该操作是在编译期就可以检查到的,这策略可在编译期就能有效的避免空指针问题。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值