Rust rust配置文件在哪如何compile 成executable?

gcc - Why does Rust fail to link on Windows? - Stack Overflow
to customize your list.
Join the Stack Overflow Community
Stack Overflow is a community of 6.5 million programmers, just like you, helping each other.
J it only takes a minute:
I downloaded and installed the Rust and Cargo nightlies on my machine, and used Cargo to generate a new binary project:
Cifram@Valyria ~
$ cargo new test --bin
Then I attempt to run this virgin project, again with a fresh, untarnished install of both Rust and Cargo, and get this:
Cifram@Valyria ~/test
$ cargo run --verbose
Compiling test v0.0.1 (file:///C:/cygwin64/home/Cifram/test)
Running `rustc C:\cygwin64\home\Cifram\test\src\main.rs --crate-name test --crate-type bin -g --out-dir C:\cygwin64\home\Cifram\test\target --dep-info C:\cygwin64\home\Cifram\test\target\.fingerprint\test-5ed143\dep-bin-test -L C:\cygwin64\home\Cifram\test\target -L C:\cygwin64\home\Cifram\test\target\deps`
error: linking with `gcc` failed: exit code: 1
note: gcc '-m64' '-L' 'C:\Program Files (x86)\Rust\bin\rustlib\x86_64-w64-mingw32\lib' '-o' 'C:\cygwin64\home\Cifram\test\target\test.exe' 'C:\cygwin64\home\Cifram\test\target\test.o' '-Wl,--whole-archive' '-lmorestack' '-Wl,--no-whole-archive' '-fno-lto' '-fno-use-linker-plugin' '-Wl,--gc-sections' '-static-libgcc' '-Wl,--enable-long-section-names' '-Wl,--nxcompat' 'C:\Program Files (x86)\Rust\bin\rustlib\x86_64-w64-mingw32\lib\libnative-4e7c5e5c.rlib' 'C:\Program Files (x86)\Rust\bin\rustlib\x86_64-w64-mingw32\lib\libstd-4e7c5e5c.rlib' 'C:\Program Files (x86)\Rust\bin\rustlib\x86_64-w64-mingw32\lib\libsync-4e7c5e5c.rlib' 'C:\Program Files (x86)\Rust\bin\rustlib\x86_64-w64-mingw32\lib\librustrt-4e7c5e5c.rlib' 'C:\Program Files (x86)\Rust\bin\rustlib\x86_64-w64-mingw32\lib\libcollections-4e7c5e5c.rlib' 'C:\Program Files (x86)\Rust\bin\rustlib\x86_64-w64-mingw32\lib\liballoc-4e7c5e5c.rlib' 'C:\Program Files (x86)\Rust\bin\rustlib\x86_64-w64-mingw32\lib\libunicode-4e7c5e5c.rlib' 'C:\Program Files (x86)\Rust\bin\rustlib\x86_64-w64-mingw32\lib\liblibc-4e7c5e5c.rlib' 'C:\Program Files (x86)\Rust\bin\rustlib\x86_64-w64-mingw32\lib\librand-4e7c5e5c.rlib' 'C:\Program Files (x86)\Rust\bin\rustlib\x86_64-w64-mingw32\lib\libcore-4e7c5e5c.rlib' '-L' 'C:\cygwin64\home\Cifram\test\target' '-L' 'C:\cygwin64\home\Cifram\test\target\deps' '-L' 'C:\cygwin64\home\Cifram\test\.rust' '-L' 'C:\cygwin64\home\Cifram\test' '-Wl,--whole-archive' '-Wl,-Bstatic' '-Wl,--no-whole-archive' '-Wl,-Bdynamic' '-lws2_32' '-lcompiler-rt'
note: C:\cygwin64\home\Cifram\test\target\test.o: file not recognized: File format not recognized
collect2.exe: error: ld returned 1 exit status
error: aborting due to previous error
Could not compile `test`.
Caused by:
Process didn't exit successfully: `rustc C:\cygwin64\home\Cifram\test\src\main.rs --crate-name test --crate-type bin -g --out-dir C:\cygwin64\home\Cifram\test\target --dep-info C:\cygwin64\home\Cifram\test\target\.fingerprint\test-5ed143\dep-bin-test -L C:\cygwin64\home\Cifram\test\target -L C:\cygwin64\home\Cifram\test\target\deps` (status=101)
I'm not sure why rustc is invoking gcc, since I understood it was built on top of LLVM. I do have gcc installed, through MinGW, so my first thought was that maybe that gcc install was interfering.
Cifram@Valyria ~
Using built-in specs.
COLLECT_GCC=C:\MinGW\bin\gcc.exe
COLLECT_LTO_WRAPPER=c:/mingw/bin/../libexec/gcc/mingw32/4.8.1/lto-wrapper.exe
Target: mingw32
Configured with: ../gcc-4.8.1/configure --prefix=/mingw --host=mingw32 --build=mingw32 --without-pic --enable-shared --enable-static --with-gnu-ld --enable-lto --enable-libssp --disable-multilib --enable-languages=c,c++,fortran,objc,obj-c++,ada --disable-sjlj-exceptions --with-dwarf2 --disable-win32-registry --enable-libstdcxx-debug --enable-version-specific-runtime-libs --with-gmp=/usr/src/pkg/gmp-5.1.2-1-mingw32-src/bld --with-mpc=/usr/src/pkg/mpc-1.0.1-1-mingw32-src/bld --with-mpfr= --with-system-zlib --with-gnu-as --enable-decimal-float=yes --enable-libgomp --enable-threads --with-libiconv-prefix=/mingw32 --with-libintl-prefix=/mingw --disable-bootstrap LDFLAGS=-s CFLAGS=-D_USE_32BIT_TIME_T
Thread model: win32
gcc version 4.8.1 (GCC)
So it's an up-to-date version of gcc. But still, it might not be what rustc is expecting. So I removed C:\MinGW\bin from my path and tried again, and got:
Cifram@Valyria ~/test
$ cargo run --verbose
Compiling test v0.0.1 (file:///C:/cygwin64/home/Cifram/test)
Running `rustc C:\cygwin64\home\Cifram\test\src\main.rs --crate-name test --crate-type bin -g --out-dir C:\cygwin64\home\Cifram\test\target --dep-info C:\cygwin64\home\Cifram\test\target\.fingerprint\test-5ed143\dep-bin-test -L C:\cygwin64\home\Cifram\test\target -L C:\cygwin64\home\Cifram\test\target\deps`
error: linking with `gcc` failed: exit code: 1
note: gcc '-m64' '-L' 'C:\Program Files (x86)\Rust\bin\rustlib\x86_64-w64-mingw32\lib' '-o' 'C:\cygwin64\home\Cifram\test\target\test.exe' 'C:\cygwin64\home\Cifram\test\target\test.o' '-Wl,--whole-archive' '-lmorestack' '-Wl,--no-whole-archive' '-fno-lto' '-fno-use-linker-plugin' '-Wl,--gc-sections' '-static-libgcc' '-Wl,--enable-long-section-names' '-Wl,--nxcompat' 'C:\Program Files (x86)\Rust\bin\rustlib\x86_64-w64-mingw32\lib\libnative-4e7c5e5c.rlib' 'C:\Program Files (x86)\Rust\bin\rustlib\x86_64-w64-mingw32\lib\libstd-4e7c5e5c.rlib' 'C:\Program Files (x86)\Rust\bin\rustlib\x86_64-w64-mingw32\lib\librand-4e7c5e5c.rlib' 'C:\Program Files (x86)\Rust\bin\rustlib\x86_64-w64-mingw32\lib\libsync-4e7c5e5c.rlib' 'C:\Program Files (x86)\Rust\bin\rustlib\x86_64-w64-mingw32\lib\librustrt-4e7c5e5c.rlib' 'C:\Program Files (x86)\Rust\bin\rustlib\x86_64-w64-mingw32\lib\libcollections-4e7c5e5c.rlib' 'C:\Program Files (x86)\Rust\bin\rustlib\x86_64-w64-mingw32\lib\liballoc-4e7c5e5c.rlib' 'C:\Program Files (x86)\Rust\bin\rustlib\x86_64-w64-mingw32\lib\liblibc-4e7c5e5c.rlib' 'C:\Program Files (x86)\Rust\bin\rustlib\x86_64-w64-mingw32\lib\libunicode-4e7c5e5c.rlib' 'C:\Program Files (x86)\Rust\bin\rustlib\x86_64-w64-mingw32\lib\libcore-4e7c5e5c.rlib' '-L' 'C:\cygwin64\home\Cifram\test\target' '-L' 'C:\cygwin64\home\Cifram\test\target\deps' '-L' 'C:\cygwin64\home\Cifram\test\.rust' '-L' 'C:\cygwin64\home\Cifram\test' '-Wl,--whole-archive' '-Wl,-Bstatic' '-Wl,--no-whole-archive' '-Wl,-Bdynamic' '-lws2_32' '-lcompiler-rt'
note: ld: this linker was not configured to use sysroots
error: aborting due to previous error
Could not compile `test`.
Caused by:
Process didn't exit successfully: `rustc C:\cygwin64\home\Cifram\test\src\main.rs --crate-name test --crate-type bin -g --out-dir C:\cygwin64\home\Cifram\test\target --dep-info C:\cygwin64\home\Cifram\test\target\.fingerprint\test-5ed143\dep-bin-test -L C:\cygwin64\home\Cifram\test\target -L C:\cygwin64\home\Cifram\test\target\deps` (status=101)
Well, it's a somewhat different error, but not really any better. The same gcc command is failing, but, before the error was:
C:\cygwin64\home\Cifram\test\target\test.o: file not recognized: File format not recognized
And now it's:
ld: this linker was not configured to use sysroots
I don't find either of these terribly meaningful. I tried running "rustc main.rs" directly. Got the same errors (except it was "src\main.o" instead of "target\test.o"). Tried doing all of this from the native Windows commandline instead of cygwin. Same errors. So it doesn't seem to be Cargo or cygwin that's to blame. I also tried downloading the last "stable" release of Rust (0.12.0), and still got the same errors. I've googled for these errors, and come up empty. So I'm running out of ideas.
Success! The problem, it turns out, is that I had also had ld installed, inside cygwin. So from what I can tell, it was using the version of gcc that ships as part of rustc, but that gcc was calling out to C:\cygwin64\bin\ld.exe, instead of it's own internal ld.
As soon as I removed ld, everything worked.
Mind you, this reinforces the point I made in my comment: Apparently I can't do Rust development and C/C++ development on the same machine at the same time. Even for the purpose of compiling C libraries I want to access in Rust, like SDL2 or GLFW. This is terribly inconvenient. If rustc needs specific versions of gcc and ld, and ships with the correct versions, it should not default to calling out to the system versions. If it needs to be possible to override it's gcc or ld versions, this should be done through an explicit commandline option.
Edit: Adding a missing "not" that inadvertently reversed the meaning of a sentence.
As an alternative solution, I manipulated the path variable when calling Rust from my cygwin shell environment. The way I understand it, is Rust will use the system path, to search for gcc, and then try to use it. By manipulating the path to remove the GCC's not wanted, it will fall back, and use the one that the rust installer came with.
PATH='/c/Program Files/Rust/bin' cargo build
*Use the correct cygwin path to where you installed Rust. On my system, this is /c/Program...
Your Answer
Sign up or
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Post as a guest
By posting your answer, you agree to the
Not the answer you're looking for?
Browse other questions tagged
rev .24586
Stack Overflow works best with JavaScript enabled& current version:
Rust 1.13 / 1.14 Nightly
18,663 downloads
Updated: November 15th, 2016
MIT License &
Description
report malware
&& 1 screenshot
A complex and advanced programming language which aims to provide users with a safe and concurrent method of developing their software
Rust is a programming language that is under constant development, aimed to provide users with a reliable means of creating client / server software which works over the Internet.
The language uses curl-braces and block expressions in order to function, featuring a self-hosted compiler, rustc.exe, which uses Low Level Virtual Machine, or LLVM, as a backend.
Dropping this executable onto an open window of Command Prompt will reveal a large proportion of its features and options, explaining their functioning in brief for programmers to understand and figure out how to use.
Some of the available options include the ability to compile and assemble without linking items, adding a directory to the library search, outputting the crate ID then exiting, exporting the generated item to a user-defined filename or setting lint warnings, and countless others.
While it may bear a visual resemblance with the C family of languages, Rust works with significantly distinct syntax and semantics, meant to support both metaprogramming and generic programming.
Since the main focus of this language is safety, the features of Rust consists of the fact that is provides memory safety, which eliminates dangling pointers as well as buffer overuns, working with a static, linear system. In terms of concurrency, this language makes use of message passing tasks, thus not sharing memory.
Moreover, Rust resorts to higher-order functions, along with pattern matching through enums, while also relying on type-parametric functions, type classes & which allow for polymorphism, and Object Oriented Style interface.
Rust requires a solid background in programming, as it is not precisely the most user-friendly of languages, but it provides users with extensive documentation on it, meaning that motivated individuals will not have a difficult time in learning at least the basics of working with it.
New in Rust 0.9:
The `float` type has been removed. Use `f32` or `f64` instead.
A new facility for enabling experimental features (feature gating) has been added, using the crate-level `#[feature(foo)]` attribute.
Managed boxes (@) are now behind a feature gate
&& && && && &&
&& && && && &&
User comments
& file size:81.2 MB
& runs on:Windows All
& category:C: \
& developer:
& homepage:
&&&Like202K
&&&Follow13KRust 1.2 稳定版发布下载,Mozilla 编程语言_Linux新闻_Linux公社-Linux系统门户网站
你好,游客
Rust 1.2 稳定版发布下载,Mozilla 编程语言
来源:oschina.net&
作者:Linux
Rust 1.2 稳定版发布下载了,该版本对编译器进行改进,包含两方面主要的性能提升:
An across-the-board improvement to real-world compiler performance. Representative crates include
(compiles 1.16x faster),
(1.62x faster),
(1.32x faster) and
(1.35x faster). You can explore some of this performance data at Nick Cameron&s , using dates
Parallel codegen is , and produces a 33% speedup when bootstrapping on a 4 core machine. Parallel codegen is particularly useful for debug builds, since it prevent but it can also be used with optimizations as an effective-O1flag. It can be activated by passing-C codegen-units=Ntorustc, whereNis the desired number of threads.
Cargo 的性能也得到提升:
Builds that do not require any recompilation (&no-op builds&) for large projects are much faster: for Servo, build time went from 5 seconds to 0.5 seconds.
Cargo now supports shared target directories that cache dependencies across multiple packages, which results in significant build-time reduction for complex projects.
同时 Rust 1.2
MSVC (Microsoft Visual C) 工具链。在语言方面 Rust 1.2 完成了
工作。详细介绍请看。
Rust 是 Mozilla 的一个新的编程语言,由web语言的领军人物Brendan Eich(js之父),Dave Herman以及Mozilla公司的Graydon Hoare 合力开发。
为什么我说 Rust 是靠谱的编程语言&
Rust 的详细介绍:Rust 的下载地址:
本文永久更新链接地址:
相关资讯 & & &
& (10月20日)
& (09月30日)
& (11月01日)
& (10月19日)
& (07月15日)
   同意评论声明
   发表
尊重网上道德,遵守中华人民共和国的各项有关法律法规
承担一切因您的行为而直接或间接导致的民事或刑事法律责任
本站管理人员有权保留或删除其管辖留言中的任意内容
本站有权在网站内转载或引用您的评论
参与本评论即表明您已经阅读并接受上述条款Rust for Python Programmers - 推酷
Rust for Python Programmers
written on Wednesday, May 27, 2015
Now that Rust 1.0 is out and quite stable, I thought it might be interesting to write an introduction to Rust for Python programmers. This guide goes over the basics of the language and compares different constructs and how they behave.
Rust language wise is a completely different beast compared to Python. Not just because one is a compiled language and the other one is interpreted, but also because the principles that go into them are completely different. However as different as the languages might be at the core, they share a lot in regards to ideas for how APIs should work. As a Python programmer a lot of concepts should feel very familiar.
The first difference you will notice as a Python programmer is the syntax. Unlike Python, Rust is a language with lots of curly braces. However this is for a good reason and that is that Rust has anonymous functions, closures and lots of chaining that Python cannot support well. These features are much easier to understand and write in a non indentation based language. Let's look at the same example in both languages.
First a Python example of printing “Hello World” three times:
def main():
for count in range(3):
print &{}. Hello World!&.format(count)
And here is the same in Rust:
fn main() {
for count in 0..3 {
println!(&{}. Hello World!&, count);
As you can see, quite similar.
and colons become braces. The other big difference syntax wise is that Rust requires type information for parameters to function which is not something you do in Python. In Python 3 type annotations are available which share the same syntax as in Rust.
One new concept compared to Python are these functions with exclamation marks at the end. Those are macros. A macro expands at compile time into something else. This for instance is used for string formatting and printing because this way the compiler can enforce correct format strings at compile time. It does not accidentally happen that you mismatch the types or number of arguments to a print function.
Traits vs Protocols
The most familiar yet different feature is object behavior. In Python a class can opt into certain behavior by implementing special methods. This is usually called “conforming to a protocol”. For instance to make an object iterable it implements the
method that returns an iterator. These methods must be implemented in the class itself and cannot
be changed afterwards (ignoring monkeypatching).
In Rust the concept is quite similar but instead of special methods, it uses traits. Traits are a bit different in that they accomplish the same goal but the implementation is locally scoped and you can implement more traits for types from another module. For instance if you want to give integers a special behavior you can do that without having to change anything about the integer type.
To compare this concept let's see how to implement a type that can be added to itself. First in Python:
class MyType(object):
def __init__(self, value):
self.value = value
def __add__(self, other):
if not isinstance(other, MyType):
return NotImplemented
return self.__class__(self.value + other.value)
And here is the same in Rust:
use std::ops::Add;
struct MyType {
value: i32,
impl MyType {
fn new(value: i32) -& MyType {
MyType { value: value }
impl Add for MyType {
type Output = MyType;
fn add(self, other: MyType) -& MyType {
MyType { value: self.value + other.value }
Here the Rust example looks a bit longer but it also comes with automatic type handling which the Python example does not do. The first thing you notice is that in Python the methods live on the class, whereas in Rust the data and the operations live independently. The
defines the data layout and the
impl MyType
define methods the type itself has, whereas
impl Add for MyType
implements the
trait for that type. For the
implementation we also need to define the result type of our add operations, but we avoid the extra complexity of having to check the type at runtime like we have to do in Python.
Another difference is that in Rust the constructor is explicit whereas in Python it's quite magical. When you create an instance of an object in Python it will eventually call
to initialize the object, whereas in Rust you just define a static method (by convention called
) which allocates and constructs the object.
Error Handling
Error handling in Python and Rust is completely different. Whereas in Python errors are thrown as exceptions, errors in Rust are passed back in the return value. This might sound strange at first but it's actually a very nice concept. It's pretty clear from looking at a function what error it returns.
This works because a function in Rust can return a
is a parametrized type which has two sides: a success and a failure side. For instance
Result&i32, MyError&
means that the function either returns a 32bit integer in the success case or
if an error happens. What happens if you need to return more than one error? This is where things differ from a philosophical point of view.
In Python a function can fail with any error and there is nothing you can do about that. If you ever used the Python “requests” library and you caught down all request exceptions and then got annoyed that SSL errors are not caught by this, you will understand the problem. There is very little you can do if a library does not document what it returns.
In Rust the situation is very different. A function signature includes the error. If you need to return two errors then the way to do this is to make a custom error type and to convert internal errors into a better one. For instance if you have an HTTP library and internally it might fail with Unicode errors, IO errors, SSL errors, what have you, you need to convert these errors into one error type specific to your library and users then only need to deal with that. Rust provides error chaining that such an error can still point back to the original error that created it if you need to.
You can also at any point use the
Box&Error&
type which any error converts into, if you are too lazy to make your own custom error type.
Where errors propagate invisibly in Python, errors propagate visibly in Rust. What this means is that you can see whenever a function returns an error even if you chose to not handle it there. This is enabled by the
macro. This example demonstrates this:
use std::fs::File;
fn read_file(path: &Path) -& Result&String, io::Error& {
let mut f = try!(File::open(path));
let mut rv = String::new();
try!(f.read_to_string(&mut rv));
File::open
read_to_string
can fail with an IO error. The
macro will propagate the error upwards and cause an early return from the function and unpack the success side. When returning the result it needs to be wrapped in either
to indicate success or
to indicate failure.
macro invokes the
trait to allow conversion of errors. For instance you could change the return value from
and implement a conversion from
by implementing the
trait and it would be automatically invoked there.
Alternatively you can change the return value from
Box&Error&
and any error can be returned. This way however you can only reason about errors at runtime and no longer at compile time.
If you don't want to handle an error and abort the execution instead, you can
a result. That way you get the success value and if the result was an error, then the program aborts.
Mutability and Ownership
The part where Rust and Python become completely different languages is the concept of mutability and ownership. Python is a garbage collected language and as a result pretty much everything can happen with the objects at runtime. You can freely pass them around and it will “just work”. Obviously you can still generate memory leaks but most problems will be resolved for you automatically at runtime.
In Rust however there is no garbage collector, yet the memory management still works automatically. This is enabled by a concept know as ownership tracking. All things you can create are owned by another thing. If you want to compare this to Python you could imagine that all objects in Python are owned by the interpreter. In Rust ownership is much more local. Function calls can have a list of objects in which case the objects are owned by the list and the list is owned by the function's scope.
More complex ownership scenarios can be expressed by lifetime annotations and the function signatures. For instance in the case of the
implementation in the previous example the receiver was called
like in Python. However unlike in Python the value is “moved” into the function whereas in Python the method is invoked with a mutable reference. What this means is that in Python you could do something like this:
leaks = []
class MyType(object):
def __add__(self, other):
leaks.append(self)
return self
a = MyType() + MyType()
Whenever you add an instance of
to another object you also leak out self to a global list. That means if you run the above example you have two references to the first instance of
: one is in
the other is in
. In Rust this is impossible. There can only ever be one owner. If you would append
the compiler would “move” the value there and you could not return it from the function because it was already moved elsewhere. You would have to move it back first to return it (for instance by removing it from the list again).
So what do you do if you need to have two references to an object? You can borrow the value. You can have an unlimited number of immutable borrows but you can only ever have one mutable borrow (and only if no immutable borrows were given out).
Functions that operate on immutable borrows are marked as
and functions that need a mutable borrow are marked as
. You can only loan out references if you are the owner. If you want to move the value out of the function (for instance by returning it) you cannot have any outstanding loans and you cannot loan out values after having moved ownership away from yourself.
This is a big change in how you think about programs but you will get used to it.
Runtime Borrows and Mutible Owners
So far pretty much all this ownership tracking was verified at compile time. But what if you cannot verify ownership at compile time? There you have multiple options to your disposal. One example is that you can use a mutex. A mutex allows you to guarantee at runtime that only one person has a mutable borrow to an object but the mutex itself owns the object. That way you can write code that access the same object but only ever once thread can access it at the time.
As a result of this this also means that you cannot accidentally forget to use a mutex and cause a data race. It would not compile.
But what if you want to program like in Python and you can't find an owner for memory? In that case you can put an object into a referenced counted wrapper and loan it out at runtime this way. That way you get very close to Python behavior just that you can cause cycles. Python breaks up cycles in it's garbage collector, Rust does not have an equivalent.
To show this in a better way, let's go with a complex Python example and the Rust equivalent:
from threading import Lock, Thread
def fib(num):
if num & 2:
return fib(num - 2) + fib(num - 1)
def thread_prog(mutex, results, i):
rv = fib(i)
with mutex:
results[i] = rv
def main():
mutex = Lock()
results = {}
threads = []
for i in xrange(35):
thread = Thread(target=thread_prog, args=(mutex, results, i))
threads.append(thread)
thread.start()
for thread in threads:
thread.join()
for i, rv in sorted(results.items()):
print &fib({}) = {}&.format(i, rv)
So what we do here is spawn 20 threads and make them compute in a very terrible manner increasing factorial numbers. Then we join the threads and print the sorted results. One thing you immediately notice here is that there is no intrinsic relationship between the mutex (the lock) and the results array.
Here is the Rust example:
use std::sync::{Arc, Mutex};
use std::collections::BTreeMap;
use std::thread;
fn fib(num: u64) -& u64 {
if num & 2 { 1 } else { fib(num - 2) + fib(num - 1) }
fn main() {
let locked_results = Arc::new(Mutex::new(BTreeMap::new()));
let threads : Vec&_& = (0..35).map(|i| {
let locked_results = locked_results.clone();
thread::spawn(move || {
let rv = fib(i);
locked_results.lock().unwrap().insert(i, rv);
}).collect();
for thread in threads { thread.join().unwrap(); }
for (i, rv) in locked_results.lock().unwrap().iter() {
println!(&fib({}) = {}&, i, rv);
The big differences to the Python version here is that we use a binary tree map instead of a hash table and we put that into an Arc'ed mutex. What's that? First of all we use a binary tree because it sorts automatically which is what we want here. Then we put it into a mutex so that we can at runtime lock it. Relationship established. Lastly we put it into an Arc. An Arc reference counts what it encloses. In this case the mutex. This means that we can make sure the mutex gets deleted only after the last thread finished running. Neat.
So here is how the code works: we count to 20 like in Python, and for each of those numbers we run a local function. Unlike in Python we can use a closure here. Then we make a copy of the Arc into the local thread. This means that each thread sees it's own version of the Arc (internally this will increment the refcount and decrement automatically when the thread dies). Then we spawn the thread with a local function. The
tells us to move the closure into the thread. Then we run the Fibonacci function in each thread. When we lock our Arc we get back a result we can
and the insert into. Ignore the
for a moment, that's just how you convert explicit results into panics. However the point is that you can only ever get the result map when you unlock the mutex. You cannot accidentally forget to lock!
Then we collect all threads into a vector. Lastly we iterate over all threads, join them and then print the results.
Two things of note here: there are very few visible types. Sure, there is the
and the Fibonacci function takes unsigned 64bit integers, but other than that, no types are visible. We can also use the binary tree map here instead of a hashtable because Rust provides us with such a type.
Iteration works exactly the same as in Python. The only difference there is that in Rust in this case we need to acquire the mutex because the compiler cannot know that the threads finished running and the mutex is not necessary. However there is an API that does not require this, it's just not stable yet in Rust 1.0.
Performance wise pretty much what you expect would happen. (This example is intentionally terrible just to show how the threading works.)
My favorite topic: Unicode :) This is where Rust and Python differ quite a bit. Python (both 2 and 3) have a very similar Unicode model which is to map Unicode data against arrays of characters where a character. In Rust however Unicode strings are always stored as UTF-8. I have covered this in the past about why this is a much better solution than what Python or C# are doing (see also
). What's however very interesting about Rust is how it deals with the ugly reality of our encoding world.
The first thing is that Rust is perfectly aware that operating system APIs (both in Windows Unicode and Linux non-Unicode land) are pretty terrible. Unlike Python however it does not try to force Unicode into these areas, instead it has different string types that can (within reason) convert between each other reasonably cheap. This works very well in practice and makes string operations very fast.
For the vast majority of programs there is no encoding/decoding necessary because they accept UTF-8, just need to run a cheap validation check, process on UTF-8 strings and then don't need an encode on the way out. If they need to integrate with Windows Unicode APIs they internally use the
which quite cheaply can convert to UCS2 like UTF-16 and back.
At any point can you convert between Unicode and bytes and munch with the bytes as you need. Then you can later run a validation step and ensure that everything went as intended. This makes writing protocols both really fast and really convenient. Compared this to the constant encoding and decoding you have to deal with in Python just to support
string indexing.
Aside from a really good storage model for Unicode it also has lots of APIs for dealing with Unicode. Either as part of the language or
. This includes case folding, categorization, Unicode regular expressions, Unicode normalization, well conforming URI/IRI/URL APIs, segmentation or just simple things as name mappings.
What's the downside? You can't do
and expect
to come back. But that's not a good idea anyways.
As an example of how interaction with the OS works, here is an example application that opens a file in the current working directory and prints the contents and the filename:
use std::env;
use std::fs;
fn example() -& Result&(), Box&Error&& {
let here = try!(env::current_dir());
println!(&Contents in: {}&, here.display());
for entry in try!(fs::read_dir(&here)) {
let path = try!(entry).path();
let md = try!(fs::metadata(&path));
println!(&
{} ({} bytes)&, path.display(), md.len());
fn main() {
example().unwrap();
All the IO operations use these
objects that were also shown before, which encapsulate the operating system's internal path properly. They might be bytes, unicode or whatever else the operating system uses but the can be formatted properly by calling
.display()
on them which return an object that can format itself into a string. This is convenient because it means you never accidentally leak out bad strings like we do in Python 3 for instance. There is a clear separation of concerns.
Distribution and Libraries
Rust comes with a combination of virtualenv+pip+setuptools called “cargo”. Well, not entirely virtualenv as it can only work with one version of Rust by default, but other than that it works as you expect. Even better than in Python land can you depend on different versions of libraries and depend on git repositories or the crates.io index. If you get rust from the website it comes with the
command that does everything you would expect.
Rust as a Python Replacement?
I don't think there is a direct relationship between Python and Rust. Python shines in scientific computing for instance and I don't think that this is something that can Rust tackle in the nearest future just because of how much work that would be. Likewise there really is no point in writing shell scripts in Rust when you can do that in Python. That being said, I think like many Python programmers started to pick up Go, even more will start to look at Rust for some areas where they previously used Python for.
It's a very powerful language, standing on strong foundations, under a very liberal license, with a very friendly community and driving by a democratic approach to language evolution.
Because Rust requires very little runtime support it's very easy to use via ctypes and CFFI with Python. I could very well envision a future where there is a Python package that would allow the distribution of a binary module written in Rust and callable from Python without any extra work from the developer needed.
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致

我要回帖

更多关于 executable 的文章

 

随机推荐