Rust の話
http://www.flickr.com/photos/lifeontheedge/246608863
about:me
• 所属
• Mozilla Japan マーケティング部
• 慶應義塾大学 特別研究教員
• @chikoski
• プログラミング言語が好き
• JavaScript, Ruby, R
清水智公 (しみずのりただ)
Rust
Its design is oriented toward concerns of
“programming in the large”, that is,
of creating and maintaining boundaries
– both abstract and operational –
that preserve large-system
integrity, availability and concurrency.
Rust の機能的な特徴
• 強い型システムと型推論
• タスクベースの並行プログラミング
• 高階関数、クロージャ
• パターンマッチ
• 多相性
C言語一門のような文法
• {} によるコードブロックの定義
• if , while による制御
• 関数定義と関数呼び出し
• main 関数
Rust
• http://www.rust-lang.org/
• 利用できる環境
• Windows (7, Server 2008 R2), x86
• Linux, x86 / x86-64
• OS X 10.6 以降, x86 / x86-64
エディタ
• Emacs : src/etc/emacs
• Vim :
https://github.com/mozilla/rust/blob/master/
src/etc/vim/syntax/rust.vim
https://github.com/wting/rust.vim
• Sublime:
https://github.com/dbp/sublime-rust
今日の内容
今日の内容
• Hello, World
• 変数宣言
• 制御構造
• 関数定義と呼び出し
version 0.6 のお話です
Hello, World
Hello, World
fn main(){
io::println("Hello, World!");
}
変数
let hi = "hi";
let mut count = 0;
while count < 10 {
io::println(fmt!("count: %?", count));
count += 1;
}
ローカル変数の宣言
let hi = "hi";
let mut count = 0;
while count < 10 {
io::println(fmt!("count: %?", count));
count += 1;
}
単一代入
let hi = "hi";
let mut count = 0;
while count < 10 {
io::println(fmt!("count: %?", count));
count += 1;
}
mutable な変数の宣言
ブロックスコープ
fn main(){
let a = 1;
{
let b = 2;
io::println(int::to_str(a));
io::println(int::to_str(b));
}
io::println(int::to_str(b));
}
ブロックスコープ
fn main(){
let a = 1;
{
let b = 2;
io::println(int::to_str(a));
io::println(int::to_str(b));
}
io::println(int::to_str(b));
}
unresolved name: `b`
グローバル変数はない
a = 10;
fn main(){
io::println(int::to_str(a));
}
グローバル変数はない
a = 10;
fn main(){
io::println(int::to_str(a));
}
expected item but found `a`
グローバル変数はない
let a = 10;
fn main(){
io::println(int::to_str(a));
}
グローバル変数はない
let a = 10;
fn main(){
io::println(int::to_str(a));
}
expected item but found `let`
定数宣言
static a: int = 10;
fn main(){
io::println(int::to_str(a));
}
定数宣言時の型宣言は省略できない
static a = 10;
fn main(){
io::println(int::to_str(a));
}
定数宣言時の型宣言は省略できない
static a = 10;
fn main(){
io::println(int::to_str(a));
}
expected `:` but found `=`
定数と同名の変数は宣言できない
static a: int = 10;
fn main(){
let a = 5;
io::println(int::to_str(a));
}
定数と同名の変数は宣言できない
static a: int = 10;
fn main(){
let a = 5;
io::println(int::to_str(a));
}
only refutable patterns allowed here
static factor: float = 57.8;
let size = factor * 10.0;
let size: int = 50;
let _size = 50;
変数宣言時の型推論
制御構造
let price = 0;
if item == "salad" {
price = 3.50;
} else if item == "muffin" {
price = 2.25;
} else {
price = 2.00;
};
条件分岐
let price =
if item == "salad" {
3.50
} else if item == "muffin" {
2.25
} else {
2.00
};
if 文ではなく if 式
fizzbuzz
let msg = if(n % 15 == 0){
"FizzBuzz"
}else if(n % 3 == 0){
"Fizz"
}else if(n % 5 == 0){
"Buzz"
}else{
""
};
パターンマッチ
match my_number {
0 => io::println("0"),
1 | 2 => io::println("1 / 2"),
3..10 => io::println("3 - 10"),
_ => io::println("?")
}
match n {
n if n % 15 == 0 => "FizzBuzz",
n if n % 5 == 0 => "Buzz",
n if n % 3 == 0 => "Fizz",
_ => ""
}
fizzbuzz (with pattern match)
match n {
n if n % 15 == 0 => "FizzBuzz",
n if n % 5 == 0 => "Buzz",
n if n % 3 == 0 => "Fizz",
_ => ""
}
ガード節
繰り返し
let mut n = 1;
while n < 100 {
let r = fizzbuzz(n);
io::println(fmt!("%? : %s", n, r));
n = n + 1;
}
loop ⇔ while(true)
let mut x = 5;
loop {
x += x - 3;
if x % 5 == 0 { break; }
io::println(int::to_str(x));
}
関数定義
関数呼び出し
fn main(){
let a = line(1, 0, 1);
io::println(int::to_str(a));
}
関数定義
fn line(a: int, b: int, x: int) -> int {
return a * x + b;
}
return は省略できる
fn line(a: int, b: int, x: int) -> int {
a * x + b
}
;の有無に注意
fn line(a: int, b: int, x: int) -> int {
a * x + b;
}
() が返り値になる
いろいろ試してみた
• 引数の型は省略できるか?
• 返り値の型は省略できるか?
• 関数内で関数定義できるか?
• 無名の関数は定義できるか?
• 関数名の重複は許されるか?
引数の型は省略できない
fn line(a, b, x){
a * x + b
}
返り値の型は省略できるが
fn line(a: int, b: int, x: int){
a * x + b
}
返り値の型は省略できるが
fn line(a: int, b: int, x: int){
a * x + b
}mismatched types: expected `()` but found
`int` (expected () but found int)
関数内関数(JavaScript の場合)
function line(a, b, x){
funciton add(a, b){
return a + b;
}
return add(a * x, b);
}
関数内で関数を宣言できる
fn line(a: int, b: int, x: int) -> int{
fn add(a: int, b: int) -> int{
return a + b
}
add(a * x, b)
}
外部の変数を参照できない
fn line(a: int, b: int, x: int) -> int{
fn add(a: int) -> int{
return a + b
}
add(a * x)
}
外部の変数を参照できない
fn line(a: int, b: int, x: int) -> int{
fn add(a: int) -> int{
return a + b
}
add(a * x)
}
この b は外側の環境にある
外部の変数を参照できない
fn line(a: int, b: int, x: int) -> int{
fn add(a: int) -> int{
return a + b
}
add(a * x)
}
attempted dynamic environment-capture
無名関数(JavaScript の場合)
function line(a, b, x){
(function(a, b){
return a + b;
})(a * x, b);
}
無名関数は作成できない(?)
fn line(a: int, b: int, x: int) -> int{
(fn(a: int, b: int) -> int{
return a + b
})(a * x, b)
}
無名関数は作成できない(?)
fn line(a: int, b: int, x: int) -> int{
(fn(a: int, b: int) -> int{
return a + b
})(a * x, b)
}
found `fn` in ident position
関数名の重複(Java の場合)
public static int line(int a, int b, int x){
return a * x + b;
}
public static float line(float a, float b, float x){
return a * x + b;
}
関数名の重複は許されない
fn line(a: int, b: int, x: int) -> int {
a * x + b
}
fn line(a: float, b: float, x: float)
-> float {
a * x + b
}
関数名の重複は許されない
fn line(a: int, b: int, x: int) -> int {
a * x + b
}
fn line(a: float, b: float, x: float)
-> float {
a * x + b
}
duplicate definition of value line
高階関数
fn line(a: int, b: int, x: int, link: &fn(int) -> int) -> int{
a * link(x) + b
}
fn offset(x: int) -> int{
x + 2
}
fn main(){
let a = line(1, 0, 1, offset);
io::println(int::to_str(a));
}
まとめ
まとめ
• 変数
• mut をつけないと mutable にならない
• グローバル変数なし
• 条件分岐:if, match
• 繰り返し:while, loop
関数について
• 型はかならず書かなければならない
• 関数内で関数を定義できる
• 無名の関数は定義できない
• 外部の環境を参照できない
• クロージャ使え
• 高階関数
本性は関数型言語
おまけと次回予告
Rust 情報源
• 公式サイト:http://www.rust-lang.org/
• メーリングリスト:
https://mail.mozilla.org/listinfo/rust-dev
• This Week in Rust:http://cmr.github.io/
• pcwalton:http://pcwalton.github.io/
• http://www.rust-.lang.jp/
ドメインだけ押さえた!翻訳者募集!
次回予告
• box
• ユーザ定義型
• タプル
• 構造体、列挙型
• オブジェクト思考
• 型推論のお話

Rust samurai#01