LearningOS/rust-based-os-comp2023

(半解决状态)运行ustlings watch 报错 thread 'main' panicked at src/main.rs:111:62:

midiexiangxxx opened this issue · 2 comments

join classroom之后按照正常流程用vscode打开自己的仓库,运行rustlings报错如下:
thread 'main' panicked at src/main.rs:111:62:
called Result::unwrap() on an Err value: Error { inner: Error { inner: TomlError { message: "unknown variant buildscript, expected one of compile, test, clippy", original: Some("# INTRO\n\n# [[exercises]]\n# name = "intro1"\n# path = "exercises/intro/intro1.rs"\n# mode = "compile"\n# hint = """\n# Remove the I AM NOT DONE comment in the exercises/intro/intro1.rs file\n# to move on to the next exercise."""\n\n[[exercises]]\nname = "intro2"\npath = "exercises/intro/intro2.rs"\nmode = "compile"\nhint = """\nAdd an argument after the format string."""\n\n# VARIABLES\n\n[[exercises]]\nname = "variables1"\npath = "exercises/variables/variables1.rs"\nmode = "compile"\nhint = """\nThe declaration on line 8 is missing a keyword that is needed in Rust\nto create a new variable binding."""\n\n[[exercises]]\nname = "variables2"\npath = "exercises/variables/variables2.rs"\nmode = "compile"\nhint = """\nThe compiler message is saying that Rust cannot infer the type that the\nvariable binding x has with what is given here.\nWhat happens if you annotate line 7 with a type annotation?\nWhat if you give x a value?\nWhat if you do both?\nWhat type should x be, anyway?\nWhat if x is the same type as 10? What if it's a different type?"""\n\n[[exercises]]\nname = "variables3"\npath = "exercises/variables/variables3.rs"\nmode = "compile"\nhint = """\nOops! In this exercise, we have a variable binding that we've created on\nline 7, and we're trying to use it on line 8, but we haven't given it a\nvalue. We can't print out something that isn't there; try giving x a value!\nThis is an error that can cause bugs that's very easy to make in any\nprogramming language -- thankfully the Rust compiler has caught this for us!"""\n\n[[exercises]]\nname = "variables4"\npath = "exercises/variables/variables4.rs"\nmode = "compile"\nhint = """\nIn Rust, variable bindings are immutable by default. But here we're trying\nto reassign a different value to x! There's a keyword we can use to make\na variable binding mutable instead."""\n\n[[exercises]]\nname = "variables5"\npath = "exercises/variables/variables5.rs"\nmode = "compile"\nhint = """\nIn variables4 we already learned how to make an immutable variable mutable\nusing a special keyword. Unfortunately this doesn't help us much in this exercise\nbecause we want to assign a different typed value to an existing variable. Sometimes\nyou may also like to reuse existing variable names because you are just converting\nvalues to different types like in this exercise.\nFortunately Rust has a powerful solution to this problem: 'Shadowing'!\nYou can read more about 'Shadowing' in the book's section 'Variables and Mutability':\nhttps://doc.rust-lang.org/book/ch03-01-variables-and-mutability.html#shadowing\nTry to solve this exercise afterwards using this technique."""\n\n[[exercises]]\nname = "variables6"\npath = "exercises/variables/variables6.rs"\nmode = "compile"\nhint = """\nWe know about variables and mutability, but there is another important type of\nvariable available: constants.\nConstants are always immutable and they are declared with keyword 'const' rather\nthan keyword 'let'.\nConstants types must also always be annotated.\n\nRead more about constants and the differences between variables and constants under 'Constants' in the book's section 'Variables and Mutability':\nhttps://doc.rust-lang.org/book/ch03-01-variables-and-mutability.html#constants\n"""\n\n# FUNCTIONS\n\n[[exercises]]\nname = "functions1"\npath = "exercises/functions/functions1.rs"\nmode = "compile"\nhint = """\nThis main function is calling a function that it expects to exist, but the\nfunction doesn't exist. It expects this function to have the name call_me.\nIt expects this function to not take any arguments and not return a value.\nSounds a lot like main, doesn't it?"""\n\n[[exercises]]\nname = "functions2"\npath = "exercises/functions/functions2.rs"\nmode = "compile"\nhint = """\nRust requires that all parts of a function's signature have type annotations,\nbut call_me is missing the type annotation of num."""\n\n[[exercises]]\nname = "functions3"\npath = "exercises/functions/functions3.rs"\nmode = "compile"\nhint = """\nThis time, the function declaration is okay, but there's something wrong\nwith the place where we're calling the function.\nAs a reminder, you can freely play around with different solutions in Rustlings!\nWatch mode will only jump to the next exercise if you remove the I AM NOT DONE comment."""\n\n[[exercises]]\nname = "functions4"\npath = "exercises/functions/functions4.rs"\nmode = "compile"\nhint = """\nThe error message points to line 17 and says it expects a type after the\n->. This is where the function's return type should be -- take a look at\nthe is_even function for an example!\n\nAlso: Did you figure out that, technically, u32 would be the more fitting type\nfor the prices here, since they can't be negative? If so, kudos!"""\n\n[[exercises]]\nname = "functions5"\npath = "exercises/functions/functions5.rs"\nmode = "compile"\nhint = """\nThis is a really common error that can be fixed by removing one character.\nIt happens because Rust distinguishes between expressions and statements: expressions return a value based on their operand(s), and statements simply return a () type which behaves just like void in C/C++ language.\nWe want to return a value of i32 type from the square function, but it is returning a () type...\nThey are not the same. There are two solutions:\n1. Add a return ahead of num * num;\n2. remove ;, make it to be num * num"""\n\n# IF\n\n[[exercises]]\nname = "if1"\npath = "exercises/if/if1.rs"\nmode = "test"\nhint = """\nIt's possible to do this in one line if you would like!\nSome similar examples from other languages:\n- In C(++) this would be: a > b ? a : b\n- In Python this would be: a if a > b else b\nRemember in Rust that:\n- the if condition does not need to be surrounded by parentheses\n- if/else conditionals are expressions\n- Each condition is followed by a {} block."""\n\n[[exercises]]\nname = "if2"\npath = "exercises/if/if2.rs"\nmode = "test"\nhint = """\nFor that first compiler error, it's important in Rust that each conditional\nblock returns the same type! To get the tests passing, you will need a couple\nconditions checking different input values."""\n\n[[exercises]]\nname = "if3"\npath = "exercises/if/if3.rs"\nmode = "test"\nhint = """\nIn Rust, every arm of an if expression has to return the same type of value. Make sure the type is consistent across all arms."""\n\n# QUIZ 1\n\n[[exercises]]\nname = "quiz1"\npath = "exercises/quiz1.rs"\nmode = "test"\nhint = "No hints this time ;)"\n\n# PRIMITIVE TYPES\n\n[[exercises]]\nname = "primitive_types1"\npath = "exercises/primitive_types/primitive_types1.rs"\nmode = "compile"\nhint = "No hints this time ;)"\n\n[[exercises]]\nname = "primitive_types2"\npath = "exercises/primitive_types/primitive_types2.rs"\nmode = "compile"\nhint = "No hints this time ;)"\n\n[[exercises]]\nname = "primitive_types3"\npath = "exercises/primitive_types/primitive_types3.rs"\nmode = "compile"\nhint = """\nThere's a shorthand to initialize Arrays with a certain size that does not\nrequire you to type in 100 items (but you certainly can if you want!).\nFor example, you can do:\nlet array = ["Are we there yet?"; 10];\n\nBonus: what are some other things you could have that would return true\nfor a.len() >= 100?"""\n\n[[exercises]]\nname = "primitive_types4"\npath = "exercises/primitive_types/primitive_types4.rs"\nmode = "test"\nhint = """\nTake a look at the Understanding Ownership -> Slices -> Other Slices section of the book:\nhttps://doc.rust-lang.org/book/ch04-03-slices.html\nand use the starting and ending indices of the items in the Array\nthat you want to end up in the slice.\n\nIf you're curious why the first argument of assert_eq! does not\nhave an ampersand for a reference since the second argument is a\nreference, take a look at the coercion chapter of the nomicon:\nhttps://doc.rust-lang.org/nomicon/coercions.html"""\n\n[[exercises]]\nname = "primitive_types5"\npath = "exercises/primitive_types/primitive_types5.rs"\nmode = "compile"\nhint = """\nTake a look at the Data Types -> The Tuple Type section of the book:\nhttps://doc.rust-lang.org/book/ch03-02-data-types.html#the-tuple-type\nParticularly the part about destructuring (second to last example in the section).\nYou'll need to make a pattern to bind name and age to the appropriate parts\nof the tuple. You can do it!!"""\n\n[[exercises]]\nname = "primitive_types6"\npath = "exercises/primitive_types/primitive_types6.rs"\nmode = "test"\nhint = """\nWhile you could use a destructuring let for the tuple here, try\nindexing into it instead, as explained in the last example of the\nData Types -> The Tuple Type section of the book:\nhttps://doc.rust-lang.org/book/ch03-02-data-types.html#the-tuple-type\nNow you have another tool in your toolbox!"""\n\n# VECS\n\n[[exercises]]\nname = "vecs1"\npath = "exercises/vecs/vecs1.rs"\nmode = "test"\nhint = """\nIn Rust, there are two ways to define a Vector.\n1. One way is to use the Vec::new() function to create a new vector\n and fill it with the push() method.\n2. The second way, which is simpler is to use the vec![] macro and\n define your elements inside the square brackets.\nCheck this chapter: https://doc.rust-lang.org/stable/book/ch08-01-vectors.html\nof the Rust book to learn more.\n"""\n\n[[exercises]]\nname = "vecs2"\npath = "exercises/vecs/vecs2.rs"\nmode = "test"\nhint = """\nHint 1: In the code, the variable element represents an item from the Vec as it is being iterated.\nCan you try multiplying this?\n\nHint 2: For the first function, there's a way to directly access the numbers stored\nin the Vec, using the * dereference operator. You can both access and write to the\nnumber that way.\n\nAfter you've completed both functions, decide for yourself which approach you like\nbetter. What do you think is the more commonly used pattern under Rust developers?\n"""\n\n# MOVE SEMANTICS\n\n[[exercises]]\nname = "move_semantics1"\npath = "exercises/move_semantics/move_semantics1.rs"\nmode = "compile"\nhint = """\nSo you've got the "cannot borrow immutable local variable vec1 as mutable" error on line 13,\nright? The fix for this is going to be adding one keyword, and the addition is NOT on line 13\nwhere the error is.\n\nAlso: Try accessing vec0 after having called fill_vec(). See what happens!"""\n\n[[exercises]]\nname = "move_semantics2"\npath = "exercises/move_semantics/move_semantics2.rs"\nmode = "compile"\nhint = """\nWhen running this exercise for the first time, you'll notice an error about\n"borrow of moved value". In Rust, when an argument is passed to a function and\nit's not explicitly returned, you can't use the original variable anymore.\nWe call this "moving" a variable. When we pass vec0 into fill_vec, it's being\n"moved" into vec1, meaning we can't access vec0 anymore after the fact.\nRust provides a couple of different ways to mitigate this issue, feel free to try them all:\n1. You could make another, separate version of the data that's in vec0 and pass that\n to fill_vec instead.\n2. Make fill_vec borrow its argument instead of taking ownership of it,\n and then copy the data within the function (vec.clone()) in order to return an owned\n Vec<i32>.\n3. Or, you could make fill_vec mutably borrow a reference to its argument (which will need to be\n mutable), modify it directly, then not return anything. This means that vec0 will change over the\n course of the function, and makes vec1 redundant (make sure to change the parameters of the println!\n statements if you go this route)\n"""\n\n[[exercises]]\nname = "move_semantics3"\npath = "exercises/move_semantics/move_semantics3.rs"\nmode = "compile"\nhint = """\nThe difference between this one and the previous ones is that the first line\nof fn fill_vec that had let mut vec = vec; is no longer there. You can,\ninstead of adding that line back, add mut in one place that will change\nan existing binding to be a mutable binding instead of an immutable one :)"""\n\n[[exercises]]\nname = "move_semantics4"\npath = "exercises/move_semantics/move_semantics4.rs"\nmode = "compile"\nhint = """\nStop reading whenever you feel like you have enough direction :) Or try\ndoing one step and then fixing the compiler errors that result!\nSo the end goal is to:\n - get rid of the first line in main that creates the new vector\n - so then vec0 doesn't exist, so we can't pass it to fill_vec\n - fill_vec has had its signature changed, which our call should reflect\n - since we're not creating a new vec in main anymore, we need to create\n a new vec in fill_vec, similarly to the way we did in main"""\n\n[[exercises]]\nname = "move_semantics5"\npath = "exercises/move_semantics/move_semantics5.rs"\nmode = "compile"\nhint = """\nCarefully reason about the range in which each mutable reference is in\nscope. Does it help to update the value of referent (x) immediately after\nthe mutable reference is taken? Read more about 'Mutable References'\nin the book's section References and Borrowing':\nhttps://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html#mutable-references.\n"""\n\n[[exercises]]\nname = "move_semantics6"\npath = "exercises/move_semantics/move_semantics6.rs"\nmode = "compile"\nhint = """\nTo find the answer, you can consult the book section "References and Borrowing":\nhttps://doc.rust-lang.org/stable/book/ch04-02-references-and-borrowing.html\nThe first problem is that get_char is taking ownership of the string.\nSo data is moved and can't be used for string_uppercase\ndata is moved to get_char first, meaning that string_uppercase cannot manipulate the data.\nOnce you've fixed that, string_uppercase's function signature will also need to be adjusted.\nCan you figure out how?\n\nAnother hint: it has to do with the & character."""\n\n# STRUCTS\n\n[[exercises]]\nname = "structs1"\npath = "exercises/structs/structs1.rs"\nmode = "test"\nhint = """\nRust has more than one type of struct. Three actually, all variants are used to package related data together.\nThere are normal (or classic) structs. These are named collections of related data stored in fields.\nTuple structs are basically just named tuples.\nFinally, Unit-like structs. These don't have any fields and are useful for generics.\n\nIn this exercise you need to complete and implement one of each kind.\nRead more about structs in The Book: https://doc.rust-lang.org/book/ch05-01-defining-structs.html\"\"\"\n\n[[exercises]]\nname = "structs2"\npath = "exercises/structs/structs2.rs"\nmode = "test"\nhint = """\nCreating instances of structs is easy, all you need to do is assign some values to its fields.\nThere are however some shortcuts that can be taken when instantiating structs.\nHave a look in The Book, to find out more: https://doc.rust-lang.org/stable/book/ch05-01-defining-structs.html#creating-instances-from-other-instances-with-struct-update-syntax\"\"\"\n\n[[exercises]]\nname = "structs3"\npath = "exercises/structs/structs3.rs"\nmode = "test"\nhint = """\nFor is_international: What makes a package international? Seems related to the places it goes through right?\n\nFor get_fees: This method takes an additional argument, is there a field in the Package struct that this relates to?\n\nHave a look in The Book, to find out more about method implementations: https://doc.rust-lang.org/book/ch05-03-method-syntax.html\"\"\"\n\n# ENUMS\n\n[[exercises]]\nname = "enums1"\npath = "exercises/enums/enums1.rs"\nmode = "compile"\nhint = "No hints this time ;)"\n\n[[exercises]]\nname = "enums2"\npath = "exercises/enums/enums2.rs"\nmode = "compile"\nhint = """\nYou can create enumerations that have different variants with different types\nsuch as no data, anonymous structs, a single string, tuples, ...etc"""\n\n[[exercises]]\nname = "enums3"\npath = "exercises/enums/enums3.rs"\nmode = "test"\nhint = """\nAs a first step, you can define enums to compile this code without errors.\nand then create a match expression in process().\nNote that you need to deconstruct some message variants\nin the match expression to get value in the variant."""\n\n# STRINGS\n\n[[exercises]]\nname = "strings1"\npath = "exercises/strings/strings1.rs"\nmode = "compile"\nhint = """\nThe current_favorite_color function is currently returning a string slice with the 'static\nlifetime. We know this because the data of the string lives in our code itself -- it doesn't\ncome from a file or user input or another program -- so it will live as long as our program\nlives. But it is still a string slice. There's one way to create a String by converting a\nstring slice covered in the Strings chapter of the book, and another way that uses the From\ntrait."""\n\n[[exercises]]\nname = "strings2"\npath = "exercises/strings/strings2.rs"\nmode = "compile"\nhint = """\nYes, it would be really easy to fix this by just changing the value bound to word to be a\nstring slice instead of a String, wouldn't it?? There is a way to add one character to line\n12, though, that will coerce the String into a string slice.\n\nSide note: If you're interested in learning about how this kind of reference conversion works, you can jump ahead in the book and read this part in the smart pointers chapter: https://doc.rust-lang.org/stable/book/ch15-02-deref.html#implicit-deref-coercions-with-functions-and-methods\"\"\"\n\n[[exercises]]\nname = "strings3"\npath = "exercises/strings/strings3.rs"\nmode = "test"\nhint = """\nThere's tons of useful standard library functions for strings. Let's try and use some of\nthem: https://doc.rust-lang.org/std/string/struct.String.html#method.trim!\n\nFor the compose_me method: You can either use the format! macro, or convert the string\nslice into an owned string, which you can then freely extend."""\n\n[[exercises]]\nname = "strings4"\npath = "exercises/strings/strings4.rs"\nmode = "compile"\nhint = "No hints this time ;)"\n\n# MODULES\n\n[[exercises]]\nname = "modules1"\npath = "exercises/modules/modules1.rs"\nmode = "compile"\nhint = """\nEverything is private in Rust by default-- but there's a keyword we can use\nto make something public! The compiler error should point to the thing that\nneeds to be public."""\n\n[[exercises]]\nname = "modules2"\npath = "exercises/modules/modules2.rs"\nmode = "compile"\nhint = """\nThe delicious_snacks module is trying to present an external interface that is\ndifferent than its internal structure (the fruits and veggies modules and\nassociated constants). Complete the use statements to fit the uses in main and\nfind the one keyword missing for both constants.\nLearn more at https://doc.rust-lang.org/book/ch07-04-bringing-paths-into-scope-with-the-use-keyword.html#re-exporting-names-with-pub-use\"\"\"\n\n[[exercises]]\nname = "modules3"\npath = "exercises/modules/modules3.rs"\nmode = "compile"\nhint = """\nUNIX_EPOCH and SystemTime are declared in the std::time module. Add a use statement\nfor these two to bring them into scope. You can use nested paths or the glob\noperator to bring these two in using only one line."""\n\n# HASHMAPS\n\n[[exercises]]\nname = "hashmaps1"\npath = "exercises/hashmaps/hashmaps1.rs"\nmode = "test"\nhint = """\nHint 1: Take a look at the return type of the function to figure out\n the type for the basket.\nHint 2: Number of fruits should be at least 5. And you have to put\n at least three different types of fruits.\n"""\n\n[[exercises]]\nname = "hashmaps2"\npath = "exercises/hashmaps/hashmaps2.rs"\nmode = "test"\nhint = """\nUse the entry() and or_insert() methods of HashMap to achieve this.\nLearn more at https://doc.rust-lang.org/stable/book/ch08-03-hash-maps.html#only-inserting-a-value-if-the-key-has-no-value\n\"\"\"\n\n[[exercises]]\nname = "hashmaps3"\npath = "exercises/hashmaps/hashmaps3.rs"\nmode = "test"\nhint = """\nHint 1: Use the entry() and or_insert() methods of HashMap to insert entries corresponding to each team in the scores table.\nLearn more at https://doc.rust-lang.org/stable/book/ch08-03-hash-maps.html#only-inserting-a-value-if-the-key-has-no-value\nHint 2: If there is already an entry for a given key, the value returned by entry() can be updated based on the existing value.\nLearn more at https://doc.rust-lang.org/book/ch08-03-hash-maps.html#updating-a-value-based-on-the-old-value\n\"\"\"\n\n# QUIZ 2\n\n[[exercises]]\nname = "quiz2"\npath = "exercises/quiz2.rs"\nmode = "test"\nhint = "No hints this time ;)"\n\n# OPTIONS\n\n[[exercises]]\nname = "options1"\npath = "exercises/options/options1.rs"\nmode = "test"\nhint = """\nOptions can have a Some value, with an inner value, or a None value, without an inner value.\nThere's multiple ways to get at the inner value, you can use unwrap, or pattern match. Unwrapping\nis the easiest, but how do you do it safely so that it doesn't panic in your face later?"""\n\n[[exercises]]\nname = "options2"\npath = "exercises/options/options2.rs"\nmode = "test"\nhint = """\ncheck out:\nhttps://doc.rust-lang.org/rust-by-example/flow_control/if_let.html\nhttps://doc.rust-lang.org/rust-by-example/flow_control/while_let.html\n\nRemember that Options can be stacked in if let and while let.\nFor example: Some(Some(variable)) = variable2\nAlso see Option::flatten\n"""\n\n[[exercises]]\nname = "options3"\npath = "exercises/options/options3.rs"\nmode = "compile"\nhint = """\nThe compiler says a partial move happened in the match\nstatement. How can this be avoided? The compiler shows the correction\nneeded. After making the correction as suggested by the compiler, do\nread: https://doc.rust-lang.org/std/keyword.ref.html\"\"\"\n\n# ERROR HANDLING\n\n[[exercises]]\nname = "errors1"\npath = "exercises/error_handling/errors1.rs"\nmode = "test"\nhint = """\nOk and Err are one of the variants of Result, so what the tests are saying\nis that generate_nametag_text should return a Result instead of an\nOption.\n\nTo make this change, you'll need to:\n - update the return type in the function signature to be a Result<String, String> that\n could be the variants Ok(String) and Err(String)\n - change the body of the function to return Ok(stuff) where it currently\n returns Some(stuff)\n - change the body of the function to return Err(error message) where it\n currently returns None"""\n\n[[exercises]]\nname = "errors2"\npath = "exercises/error_handling/errors2.rs"\nmode = "test"\nhint = """\nOne way to handle this is using a match statement on\nitem_quantity.parse::<i32>() where the cases are Ok(something) and\nErr(something). This pattern is very common in Rust, though, so there's\na ? operator that does pretty much what you would make that match statement\ndo for you! Take a look at this section of the Error Handling chapter:\nhttps://doc.rust-lang.org/book/ch09-02-recoverable-errors-with-result.html#a-shortcut-for-propagating-errors-the--operator\nand give it a try!"""\n\n[[exercises]]\nname = "errors3"\npath = "exercises/error_handling/errors3.rs"\nmode = "compile"\nhint = """\nIf other functions can return a Result, why shouldn't main? It's a fairly common\nconvention to return something like Result<(), ErrorType> from your main function.\nThe unit (()) type is there because nothing is really needed in terms of positive\nresults."""\n\n[[exercises]]\nname = "errors4"\npath = "exercises/error_handling/errors4.rs"\nmode = "test"\nhint = """\nPositiveNonzeroInteger::new is always creating a new instance and returning an Ok result.\nIt should be doing some checking, returning an Err result if those checks fail, and only\nreturning an Ok result if those checks determine that everything is... okay :)"""\n\n[[exercises]]\nname = "errors5"\npath = "exercises/error_handling/errors5.rs"\nmode = "compile"\nhint = """\nThere are two different possible Result types produced within main(), which are\npropagated using ? operators. How do we declare a return type from main() that allows both?\n\nUnder the hood, the ? operator calls From::from on the error value to convert it to a boxed\ntrait object, a Box<dyn error::Error>. This boxed trait object is polymorphic, and since all\nerrors implement the error::Error trait, we can capture lots of different errors in one "Box"\nobject.\n\nCheck out this section of the book:\nhttps://doc.rust-lang.org/book/ch09-02-recoverable-errors-with-result.html#a-shortcut-for-propagating-errors-the--operator\n\nRead more about boxing errors:\nhttps://doc.rust-lang.org/stable/rust-by-example/error/multiple_error_types/boxing_errors.html\n\nRead more about using the ? operator with boxed errors:\nhttps://doc.rust-lang.org/stable/rust-by-example/error/multiple_error_types/reenter_question_mark.html\n"""\n\n[[exercises]]\nname = "errors6"\npath = "exercises/error_handling/errors6.rs"\nmode = "test"\nhint = """\nThis exercise uses a completed version of PositiveNonzeroInteger from\nerrors4.\n\nBelow the line that TODO asks you to change, there is an example of using\nthe map_err() method on a Result to transform one type of error into\nanother. Try using something similar on the Result from parse(). You\nmight use the ? operator to return early from the function, or you might\nuse a match expression, or maybe there's another way!\n\nYou can create another function inside impl ParsePosNonzeroError to use\nwith map_err().\n\nRead more about map_err() in the std::result documentation:\nhttps://doc.rust-lang.org/std/result/enum.Result.html#method.map_err"""\n\n# Generics\n\n[[exercises]]\nname = "generics1"\npath = "exercises/generics/generics1.rs"\nmode = "compile"\nhint = """\nVectors in Rust make use of generics to create dynamically sized arrays of any type.\nYou need to tell the compiler what type we are pushing onto this vector."""\n\n[[exercises]]\nname = "generics2"\npath = "exercises/generics/generics2.rs"\nmode = "test"\nhint = """\nCurrently we are wrapping only values of type 'u32'.\nMaybe we could update the explicit references to this data type somehow?\n\nIf you are still stuck https://doc.rust-lang.org/stable/book/ch10-01-syntax.html#in-method-definitions\n\"\"\"\n\n# TRAITS\n\n[[exercises]]\nname = "traits1"\npath = "exercises/traits/traits1.rs"\nmode = "test"\nhint = """\nA discussion about Traits in Rust can be found at:\nhttps://doc.rust-lang.org/book/ch10-02-traits.html\n"""\n\n[[exercises]]\nname = "traits2"\npath = "exercises/traits/traits2.rs"\nmode = "test"\nhint = """\nNotice how the trait takes ownership of 'self',and returns Self.\nTry mutating the incoming string vector. Have a look at the tests to see\nwhat the result should look like!\n\nVectors provide suitable methods for adding an element at the end. See\nthe documentation at: https://doc.rust-lang.org/std/vec/struct.Vec.html\"\"\"\n\n[[exercises]]\nname = "traits3"\npath = "exercises/traits/traits3.rs"\nmode = "test"\nhint = """\nTraits can have a default implementation for functions. Structs that implement\nthe trait can then use the default version of these functions if they choose not\nimplement the function themselves.\n\nSee the documentation at: https://doc.rust-lang.org/book/ch10-02-traits.html#default-implementations\n\"\"\"\n\n[[exercises]]\nname = "traits4"\npath = "exercises/traits/traits4.rs"\nmode = "test"\nhint = """\nInstead of using concrete types as parameters you can use traits. Try replacing the\n'??' with 'impl <what goes here?>'\n\nSee the documentation at: https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters\n\"\"\"\n\n[[exercises]]\nname = "traits5"\npath = "exercises/traits/traits5.rs"\nmode = "compile"\nhint = """\nTo ensure a parameter implements multiple traits use the '+ syntax'. Try replacing the\n'??' with 'impl <> + <>'.\n\nSee the documentation at: https://doc.rust-lang.org/book/ch10-02-traits.html#specifying-multiple-trait-bounds-with-the--syntax\n\"\"\"\n\n# QUIZ 3\n\n[[exercises]]\nname = "quiz3"\npath = "exercises/quiz3.rs"\nmode = "test"\nhint = """\nTo find the best solution to this challenge you're going to need to think back to your\nknowledge of traits, specifically Trait Bound Syntax - you may also need this: use std::fmt::Display;."""\n\n# LIFETIMES\n\n[[exercises]]\nname = "lifetimes1"\npath = "exercises/lifetimes/lifetimes1.rs"\nmode = "compile"\nhint = """\nLet the compiler guide you. Also take a look at the book if you need help:\nhttps://doc.rust-lang.org/book/ch10-03-lifetime-syntax.html"""\n\n[[exercises]]\nname = "lifetimes2"\npath = "exercises/lifetimes/lifetimes2.rs"\nmode = "compile"\nhint = """\nRemember that the generic lifetime 'a will get the concrete lifetime that is equal to the smaller of the lifetimes of x and y.\nYou can take at least two paths to achieve the desired result while keeping the inner block:\n1. Move the string2 declaration to make it live as long as string1 (how is result declared?)\n2. Move println! into the inner block"""\n\n[[exercises]]\nname = "lifetimes3"\npath = "exercises/lifetimes/lifetimes3.rs"\nmode = "compile"\nhint = """\nIf you use a lifetime annotation in a struct's fields, where else does it need to be added?"""\n\n# TESTS\n\n[[exercises]]\nname = "tests1"\npath = "exercises/tests/tests1.rs"\nmode = "test"\nhint = """\nYou don't even need to write any code to test -- you can just test values and run that, even\nthough you wouldn't do that in real life :) assert! is a macro that needs an argument.\nDepending on the value of the argument, assert! will do nothing (in which case the test will\npass) or assert! will panic (in which case the test will fail). So try giving different values\nto assert! and see which ones compile, which ones pass, and which ones fail :)"""\n\n[[exercises]]\nname = "tests2"\npath = "exercises/tests/tests2.rs"\nmode = "test"\nhint = """\nLike the previous exercise, you don't need to write any code to get this test to compile and\nrun. assert_eq! is a macro that takes two arguments and compares them. Try giving it two\nvalues that are equal! Try giving it two arguments that are different! Try giving it two values\nthat are of different types! Try switching which argument comes first and which comes second!"""\n\n[[exercises]]\nname = "tests3"\npath = "exercises/tests/tests3.rs"\nmode = "test"\nhint = """\nYou can call a function right where you're passing arguments to assert! -- so you could do\nsomething like assert!(having_fun()). If you want to check that you indeed get false, you\ncan negate the result of what you're doing using !, like assert!(!having_fun())."""\n\n[[exercises]]\nname = "tests4"\npath = "exercises/tests/tests4.rs"\nmode = "test"\nhint = """\nWe expect method Rectangle::new() to panic for negative values.\nTo handle that you need to add a special attribute to the test function.\nYou can refer to the docs:\nhttps://doc.rust-lang.org/stable/book/ch11-01-writing-tests.html#checking-for-panics-with-should_panic"""\n\n\n# STANDARD LIBRARY TYPES\n\n[[exercises]]\nname = "iterators1"\npath = "exercises/iterators/iterators1.rs"\nmode = "compile"\nhint = """\nStep 1:\nWe need to apply something to the collection my_fav_fruits before we start to go through\nit. What could that be? Take a look at the struct definition for a vector for inspiration:\nhttps://doc.rust-lang.org/std/vec/struct.Vec.html\nStep 2 & step 3:\nVery similar to the lines above and below. You've got this!\nStep 4:\nAn iterator goes through all elements in a collection, but what if we've run out of\nelements? What should we expect here? If you're stuck, take a look at\nhttps://doc.rust-lang.org/std/iter/trait.Iterator.html for some ideas.\n"""\n\n[[exercises]]\nname = "iterators2"\npath = "exercises/iterators/iterators2.rs"\nmode = "test"\nhint = """\nStep 1\nThe variable first is a char. It needs to be capitalized and added to the\nremaining characters in c in order to return the correct String.\nThe remaining characters in c can be viewed as a string slice using the\nas_str method.\nThe documentation for char contains many useful methods.\nhttps://doc.rust-lang.org/std/primitive.char.html\n\nStep 2\nCreate an iterator from the slice. Transform the iterated values by applying\nthe capitalize_first function. Remember to collect the iterator.\n\nStep 3.\nThis is surprisingly similar to the previous solution. Collect is very powerful\nand very general. Rust just needs to know the desired type."""\n\n[[exercises]]\nname = "iterators3"\npath = "exercises/iterators/iterators3.rs"\nmode = "test"\nhint = """\nThe divide function needs to return the correct error when even division is not\npossible.\n\nThe division_results variable needs to be collected into a collection type.\n\nThe result_with_list function needs to return a single Result where the success\ncase is a vector of integers and the failure case is a DivisionError.\n\nThe list_of_results function needs to return a vector of results.\n\nSee https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.collect for how\nthe FromIterator trait is used in collect(). This trait is REALLY powerful! It\ncan make the solution to this exercise infinitely easier."""\n\n[[exercises]]\nname = "iterators4"\npath = "exercises/iterators/iterators4.rs"\nmode = "test"\nhint = """\nIn an imperative language, you might write a for loop that updates\na mutable variable. Or, you might write code utilizing recursion\nand a match clause. In Rust you can take another functional\napproach, computing the factorial elegantly with ranges and iterators.\n\nHint 2: Check out the fold and rfold methods!"""\n\n[[exercises]]\nname = "iterators5"\npath = "exercises/iterators/iterators5.rs"\nmode = "test"\nhint = """\nThe documentation for the std::iter::Iterator trait contains numerous methods\nthat would be helpful here.\n\nThe collection variable in count_collection_iterator is a slice of HashMaps. It\nneeds to be converted into an iterator in order to use the iterator methods.\n\nThe fold method can be useful in the count_collection_iterator function.\n\nFor a further challenge, consult the documentation for Iterator to find\na different method that could make your code more compact than using fold."""\n\n# SMART POINTERS\n\n[[exercises]]\nname = "box1"\npath = "exercises/smart_pointers/box1.rs"\nmode = "test"\nhint = """\nStep 1\nThe compiler's message should help: since we cannot store the value of the actual type\nwhen working with recursive types, we need to store a reference (pointer) to its value.\nWe should, therefore, place our List inside a Box. More details in the book here:\nhttps://doc.rust-lang.org/book/ch15-01-box.html#enabling-recursive-types-with-boxes\n\nStep 2\nCreating an empty list should be fairly straightforward (hint: peek at the assertions).\nFor a non-empty list keep in mind that we want to use our Cons "list builder".\nAlthough the current list is one of integers (i32), feel free to change the definition\nand try other types!\n"""\n\n[[exercises]]\nname = "rc1"\npath = "exercises/smart_pointers/rc1.rs"\nmode = "compile"\nhint = """\nThis is a straightforward exercise to use the Rc type. Each Planet has\nownership of the Sun, and uses Rc::clone() to increment the reference count of the Sun.\nAfter using drop() to move the Planets out of scope individually, the reference count goes down.\nIn the end the sun only has one reference again, to itself. See more at:\nhttps://doc.rust-lang.org/book/ch15-04-rc.html\n\n* Unfortunately Pluto is no longer considered a planet :(\n"""\n\n[[exercises]]\nname = "arc1"\npath = "exercises/smart_pointers/arc1.rs"\nmode = "compile"\nhint = """\nMake shared_numbers be an Arc from the numbers vector. Then, in order\nto avoid creating a copy of numbers, you'll need to create child_numbers\ninside the loop but still in the main thread.\n\nchild_numbers should be a clone of the Arc of the numbers instead of a\nthread-local copy of the numbers.\n\nThis is a simple exercise if you understand the underlying concepts, but if this\nis too much of a struggle, consider reading through all of Chapter 16 in the book:\nhttps://doc.rust-lang.org/stable/book/ch16-00-concurrency.html\n"""\n\n[[exercises]]\nname = "cow1"\npath = "exercises/smart_pointers/cow1.rs"\nmode = "test"\nhint = """\nIf Cow already owns the data it doesn't need to clone it when to_mut() is called.\n\nCheck out https://doc.rust-lang.org/std/borrow/enum.Cow.html for documentation\non the Cow type.\n"""\n\n# THREADS\n\n[[exercises]]\nname = "threads1"\npath = "exercises/threads/threads1.rs"\nmode = "compile"\nhint = """\nJoinHandle is a struct that is returned from a spawned thread:\nhttps://doc.rust-lang.org/std/thread/fn.spawn.html\n\nA challenge with multi-threaded applications is that the main thread can\nfinish before the spawned threads are completed.\nhttps://doc.rust-lang.org/book/ch16-01-threads.html#waiting-for-all-threads-to-finish-using-join-handles\n\nUse the JoinHandles to wait for each thread to finish and collect their results.\nhttps://doc.rust-lang.org/std/thread/struct.JoinHandle.html\n"""\n\n[[exercises]]\nname = "threads2"\npath = "exercises/threads/threads2.rs"\nmode = "compile"\nhint = """\nArc is an Atomic Reference Counted pointer that allows safe, shared access\nto immutable data. But we want to change the number of jobs_completed\nso we'll need to also use another type that will only allow one thread to\nmutate the data at a time. Take a look at this section of the book:\nhttps://doc.rust-lang.org/book/ch16-03-shared-state.html#atomic-reference-counting-with-arct\nand keep reading if you'd like more hints :)\n\n\nDo you now have an Arc Mutex JobStatus at the beginning of main? Like:\nlet status = Arc::new(Mutex::new(JobStatus { jobs_completed: 0 }));\nSimilar to the code in the example in the book that happens after the text\nthat says "We can use Arc to fix this.". If not, give that a try! If you\ndo and would like more hints, keep reading!!\n\n\nMake sure neither of your threads are holding onto the lock of the mutex\nwhile they are sleeping, since this will prevent the other thread from\nbeing allowed to get the lock. Locks are automatically released when\nthey go out of scope.\n\nIf you've learned from the sample solutions, I encourage you to come\nback to this exercise and try it again in a few days to reinforce\nwhat you've learned :)"""\n\n[[exercises]]\nname = "threads3"\npath = "exercises/threads/threads3.rs"\nmode = "compile"\nhint = """\nAn alternate way to handle concurrency between threads is to use\na mpsc (multiple producer, single consumer) channel to communicate.\nWith both a sending end and a receiving end, it's possible to\nsend values in one thread and receive them in another.\nMultiple producers are possible by using clone() to create a duplicate\nof the original sending end.\nSee https://doc.rust-lang.org/book/ch16-02-message-passing.html for more info.\n"""\n\n# MACROS\n\n[[exercises]]\nname = "macros1"\npath = "exercises/macros/macros1.rs"\nmode = "compile"\nhint = """\nWhen you call a macro, you need to add something special compared to a\nregular function call. If you're stuck, take a look at what's inside\nmy_macro."""\n\n[[exercises]]\nname = "macros2"\npath = "exercises/macros/macros2.rs"\nmode = "compile"\nhint = """\nMacros don't quite play by the same rules as the rest of Rust, in terms of\nwhat's available where.\n\nUnlike other things in Rust, the order of "where you define a macro" versus\n"where you use it" actually matters."""\n\n[[exercises]]\nname = "macros3"\npath = "exercises/macros/macros3.rs"\nmode = "compile"\nhint = """\nIn order to use a macro outside of its module, you need to do something\nspecial to the module to lift the macro out into its parent.\n\nThe same trick also works on "extern crate" statements for crates that have\nexported macros, if you've seen any of those around."""\n\n[[exercises]]\nname = "macros4"\npath = "exercises/macros/macros4.rs"\nmode = "compile"\nhint = """\nYou only need to add a single character to make this compile.\nThe way macros are written, it wants to see something between each\n"macro arm", so it can separate them.\n\nThat's all the macro exercises we have in here, but it's barely even\nscratching the surface of what you can do with Rust's macros. For a more\nthorough introduction, you can have a read through the little book of Rust\nmacros: https://veykril.github.io/tlborm/\"\"\"\n\n# CLIPPY\n\n[[exercises]]\nname = "clippy1"\npath = "exercises/clippy/clippy1.rs"\nmode = "clippy"\nhint = """\nRust stores the highest precision version of any long or infinite precision\nmathematical constants in the Rust standard library.\nhttps://doc.rust-lang.org/stable/std/f32/consts/index.html\n\nWe may be tempted to use our own approximations for certain mathematical constants,\nbut clippy recognizes those imprecise mathematical constants as a source of\npotential error.\nSee the suggestions of the clippy warning in compile output and use the\nappropriate replacement constant from std::f32::consts..."""\n\n[[exercises]]\nname = "clippy2"\npath = "exercises/clippy/clippy2.rs"\nmode = "clippy"\nhint = """\nfor loops over Option values are more clearly expressed as an if let"""\n\n[[exercises]]\nname = "clippy3"\npath = "exercises/clippy/clippy3.rs"\nmode = "clippy"\nhint = "No hints this time!"\n\n# TYPE CONVERSIONS\n\n[[exercises]]\nname = "using_as"\npath = "exercises/conversions/using_as.rs"\nmode = "test"\nhint = """\nUse the as operator to cast one of the operands in the last line of the\naverage function into the expected return type."""\n\n[[exercises]]\nname = "from_into"\npath = "exercises/conversions/from_into.rs"\nmode = "test"\nhint = """\nFollow the steps provided right before the From implementation"""\n\n[[exercises]]\nname = "from_str"\npath = "exercises/conversions/from_str.rs"\nmode = "test"\nhint = """\nThe implementation of FromStr should return an Ok with a Person object,\nor an Err with an error if the string is not valid.\n\nThis is almost like the from_into exercise, but returning errors instead\nof falling back to a default value.\n\nLook at the test cases to see which error variants to return.\n\nAnother hint: You can use the map_err method of Result with a function\nor a closure to wrap the error from parse::<usize>.\n\nYet another hint: If you would like to propagate errors by using the ?\noperator in your solution, you might want to look at\nhttps://doc.rust-lang.org/stable/rust-by-example/error/multiple_error_types/reenter_question_mark.html\n"""\n\n[[exercises]]\nname = "try_from_into"\npath = "exercises/conversions/try_from_into.rs"\nmode = "test"\nhint = """\nFollow the steps provided right before the TryFrom implementation.\nYou can also use the example at https://doc.rust-lang.org/std/convert/trait.TryFrom.html\n\nIs there an implementation of TryFrom in the standard library that\ncan both do the required integer conversion and check the range of the input?\n\nAnother hint: Look at the test cases to see which error variants to return.\n\nYet another hint: You can use the map_err or or methods of Result to\nconvert errors.\n\nYet another hint: If you would like to propagate errors by using the ?\noperator in your solution, you might want to look at\nhttps://doc.rust-lang.org/stable/rust-by-example/error/multiple_error_types/reenter_question_mark.html\n\nChallenge: Can you make the TryFrom implementations generic over many integer types?"""\n\n[[exercises]]\nname = "as_ref_mut"\npath = "exercises/conversions/as_ref_mut.rs"\nmode = "test"\nhint = """\nAdd AsRef or AsMut as a trait bound to the functions."""\n\n\n# 强化训练 TESTS\n\n[[exercises]]\nname = "tests5"\npath = "exercises/tests/tests5.rs"\nmode = "test"\nhint = """\nFor more information about unsafe and soundness, see\nhttps://doc.rust-lang.org/nomicon/safe-unsafe-meaning.html"""\n\n[[exercises]]\nname = "tests6"\npath = "exercises/tests/tests6.rs"\nmode = "test"\nhint = """\nThe function to transform a box to a raw pointer is called Box::into_raw, while\nthe function to reconstruct a box from a raw pointer is called Box::from_raw.\nSearch the official API documentation for more information:\nhttps://doc.rust-lang.org/nightly/std/index.html"""\n\n[[exercises]]\nname = "tests7"\npath = "exercises/tests/tests7.rs"\nmode = "buildscript"\nhint = """\nThe command to set up an environment variable is "rustc-env=VAR=VALUE"."""\n\n[[exercises]]\nname = "tests8"\npath = "exercises/tests/tests8.rs"\nmode = "buildscript"\nhint = """\nThe command to set up an environment variable is "rustc-cfg=CFG[="VALUE"]", while\nthe square brackets means optional. Be sure what CFG and VALUE you want here."""\n\n[[exercises]]\nname = "tests9"\npath = "exercises/tests/tests9.rs"\nmode = "test"\nhint = "No hints this time!"\n"), keys: ["exercises", "mode"], span: Some(43265..43278) } } }
note: run with RUST_BACKTRACE=1 environment variable to display a backtrace

阅读报错之后可以发现环境变量只有compile, test, clippy三个,但是test7 test8的mode为buildscript,不存在,于是不能运行,暂时将buildscript改为test可以运行。目前还没做到test7,test8,做完了来填坑。

做完test7来填坑,解决了,很尴尬,是我自己环境配置的问题,用的class里的仓库和本地的rustlings,应该先执行cargo uninstall rustlings,然后cargo install --path .,安装好环境就可以了,rustlings watch也没有报错