How are Rust's Arc and Rc types different from having garbage collection?

后端 未结 4 1815
孤独总比滥情好
孤独总比滥情好 2021-01-12 19:09

The Rust Programming Language, first edition says that Rust does not have a garbage collector:

It maintains these goals without having a garbage colle

相关标签:
4条回答
  • 2021-01-12 19:09

    This article is a bit old, regarding how Rust has changed now, but it highlights what it means that Rust does not have GC. Only RAII and ownership are intrinsic to Rust. They helps writing reference-counting alike GCs such as Rc and Arc, but those are not part of the language, they're part of the standard library. And it makes a huge difference.

    If you consider writing an operating system in Rust, you can't use any form of GC in part of your code or use the standard library. At this level, it's important to know what is part of the language and what is not. For a simple example, have look here.

    In contrast, in a language such as Java or Python, you can't prevent your code from using the GC as it use it implicitly by design of the language.

    In Rust, like in C/C++ a GC is part from a library and it's use is explicit.

    0 讨论(0)
  • 2021-01-12 19:22

    If you insist on being correct, a garbage collector collects. It collects a list of memory locations to free. Rc/Arc on the other hand does not, so I don't think you can call it garbage collection.

    However rust has the std::gc module, so yea rust has in fact an optional garbage collector for now.

    0 讨论(0)
  • 2021-01-12 19:25

    Rc has no cycle collection. If you create a cycle of references, you will probably crash the program as it tries to increment the refcount.

    Though this technically counts as a garbage collector too, it's not a universally useful one since you have the restriction on the types it can contain.

    0 讨论(0)
  • 2021-01-12 19:32

    I consider garbage collection to be any process which prevents the need for manual deallocation of dynamically-allocated memory

    Then Rust does have "garbage collection"!

    fn make_stuff() {
        // Allocate memory on the heap and store `true` in it
        let thing = Box::new(true);
        // Allocate memory on the heap and store 1000 numbers in it.
        let things = vec![42; 1000];
    } // Look Ma! No manual deallocation!
    

    When thing and things go out of scope (in this case, at the end of the method), then the memory they had allocated will be freed for you.

    Rc and Arc allow more flexibility than this; you should give their docs a read to know more.


    In addition to @Manishearth's answer, there's also this detail (emphasis mine):

    automatically freed at the end of its last owner's lifetime

    In many garbage-collected languages, garbage collection happens out-of-band with the rest of your code. In Rust, the location of deallocation will be known.

    Given this Java:

    public static ArrayList alpha()
    {
        return new ArrayList();
    }
    
    public static void beta()
    {
        alpha(); // Unused result
    }
    

    I do not believe that you can say with certainty when the ArrayList will be removed from memory. In the equivalent Rust code, you know that an Arc or Rc will be destructed as soon as it goes out of scope.

    0 讨论(0)
提交回复
热议问题