V言語入門:シンプルで高速なシステムプログラミング言語完全ガイド
V言語入門:シンプルで高速なシステムプログラミング言語完全ガイド
V言語(Vlang)は、シンプルさ、安全性、高速性を追求した新しいシステムプログラミング言語です。Go、Rust、Pythonの良いところを取り入れながら、より学びやすく、より高速なコンパイルを実現しています。
V言語とは
V言語は2019年に登場した比較的新しい言語で、以下の特徴を持ちます。
主な特徴
- シンプル: 学習コストが低く、数時間でマスター可能
- 高速: C並みのパフォーマンス、1秒未満のコンパイル時間
- 安全: null、グローバル変数、未定義動作なし
- メモリ安全: 自動メモリ管理(ガベージコレクタ不要)
- 並行処理: 軽量スレッド(coroutines)のネイティブサポート
- クロスプラットフォーム: Windows、macOS、Linux対応
- 小さなバイナリ: 最小100KB程度の実行ファイル
インストール
V言語のインストールは非常に簡単です。
macOS/Linux
git clone https://github.com/vlang/v
cd v
make
sudo ./v symlink
Windows
git clone https://github.com/vlang/v
cd v
make.bat
.\v.exe symlink
バージョン確認
v version
Hello, World!
最もシンプルなVプログラムから始めましょう。
// hello.v
fn main() {
println('Hello, World!')
}
実行方法:
# 直接実行
v run hello.v
# コンパイルしてから実行
v hello.v
./hello
基本的な構文
変数宣言
Vでは、変数は不変(immutable)がデフォルトです。
fn main() {
// 不変変数
name := 'Alice'
age := 30
// 型推論が働く
is_active := true
score := 95.5
// 型を明示することも可能
mut counter := 0 // 可変変数
// 再代入(mutが必要)
counter = counter + 1
counter += 1
println('Name: $name, Age: $age, Counter: $counter')
}
データ型
Vは静的型付け言語です。
fn main() {
// 整数型
i8_val := i8(127) // 8ビット符号付き整数
i16_val := i16(32767) // 16ビット
i32_val := 2147483647 // 32ビット(デフォルト)
i64_val := i64(9223372036854775807) // 64ビット
// 符号なし整数
u8_val := u8(255)
u16_val := u16(65535)
u32_val := u32(4294967295)
u64_val := u64(18446744073709551615)
// 浮動小数点数
f32_val := f32(3.14)
f64_val := 3.14159265359 // デフォルト
// 真偽値
is_valid := true
// 文字列
message := 'Hello, V!'
multiline := '
This is a
multiline string
'
// 配列
numbers := [1, 2, 3, 4, 5]
// マップ
ages := {
'Alice': 30
'Bob': 25
}
}
文字列操作
Vの文字列は不変で、UTF-8をネイティブサポートします。
fn main() {
// 文字列補間
name := 'Alice'
age := 30
message := 'My name is $name and I am $age years old'
println(message)
// 式も埋め込める
println('Next year I will be ${age + 1} years old')
// 文字列メソッド
text := 'Hello, World!'
println(text.to_upper()) // HELLO, WORLD!
println(text.to_lower()) // hello, world!
println(text.contains('World')) // true
println(text.starts_with('Hello')) // true
println(text.replace('World', 'V')) // Hello, V!
// 文字列の分割と結合
words := text.split(',')
println(words) // ['Hello', ' World!']
joined := words.join(' | ')
println(joined) // Hello | World!
// 文字列の長さ
println(text.len) // 13
}
配列
Vの配列は型安全で、動的にサイズ変更できます。
fn main() {
// 配列の作成
mut numbers := [1, 2, 3, 4, 5]
// 要素へのアクセス
println(numbers[0]) // 1
println(numbers[1]) // 2
// 要素の追加
numbers << 6
numbers << 7
println(numbers) // [1, 2, 3, 4, 5, 6, 7]
// スライス
slice := numbers[1..4] // [2, 3, 4]
println(slice)
// 配列の長さ
println(numbers.len) // 7
// イテレーション
for i, num in numbers {
println('Index $i: $num')
}
// フィルター
evens := numbers.filter(it % 2 == 0)
println(evens) // [2, 4, 6]
// マップ
doubled := numbers.map(it * 2)
println(doubled) // [2, 4, 6, 8, 10, 12, 14]
// 配列の合計
sum := numbers.reduce(fn (acc int, x int) int {
return acc + x
}, 0)
println('Sum: $sum')
}
マップ
fn main() {
// マップの作成
mut ages := map[string]int{}
ages['Alice'] = 30
ages['Bob'] = 25
ages['Charlie'] = 35
// または
mut scores := {
'Alice': 95
'Bob': 87
'Charlie': 92
}
// 値の取得
println(ages['Alice']) // 30
// キーの存在確認
if 'Alice' in ages {
println('Alice is in the map')
}
// 全要素をイテレート
for name, age in ages {
println('$name is $age years old')
}
// キーの削除
ages.delete('Bob')
// マップのサイズ
println(ages.len)
}
制御構造
if文
fn main() {
age := 20
// 基本的なif
if age >= 18 {
println('Adult')
} else {
println('Minor')
}
// if式(値を返す)
status := if age >= 18 {
'adult'
} else {
'minor'
}
println(status)
// if is(型チェック)
value := 'Hello'
if value is string {
println('It is a string')
}
}
match文
Vのmatchは、他言語のswitchに相当しますが、より強力です。
fn main() {
// 基本的なmatch
day := 3
day_name := match day {
1 { 'Monday' }
2 { 'Tuesday' }
3 { 'Wednesday' }
4 { 'Thursday' }
5 { 'Friday' }
6, 7 { 'Weekend' }
else { 'Invalid' }
}
println(day_name)
// 範囲を使ったmatch
score := 85
grade := match score {
90..100 { 'A' }
80..89 { 'B' }
70..79 { 'C' }
60..69 { 'D' }
else { 'F' }
}
println('Grade: $grade')
}
ループ
fn main() {
// for: 範囲ループ
for i in 0 .. 5 {
println(i) // 0, 1, 2, 3, 4
}
// for: 配列のイテレーション
fruits := ['apple', 'banana', 'cherry']
for fruit in fruits {
println(fruit)
}
// for: インデックス付き
for i, fruit in fruits {
println('$i: $fruit')
}
// for: 条件付き(while相当)
mut counter := 0
for counter < 5 {
println(counter)
counter++
}
// for: 無限ループ
mut x := 0
for {
x++
if x > 10 {
break
}
if x % 2 == 0 {
continue
}
println(x)
}
}
関数
// 基本的な関数
fn add(a int, b int) int {
return a + b
}
// 同じ型の引数は省略可能
fn multiply(a int, b int) int {
return a * b
}
// 複数の返り値
fn divide(a int, b int) (int, int) {
quotient := a / b
remainder := a % b
return quotient, remainder
}
// オプショナルな返り値
fn safe_divide(a int, b int) ?f64 {
if b == 0 {
return error('Division by zero')
}
return f64(a) / f64(b)
}
// 可変長引数
fn sum(nums ...int) int {
mut total := 0
for num in nums {
total += num
}
return total
}
fn main() {
println(add(5, 3)) // 8
q, r := divide(17, 5)
println('Quotient: $q, Remainder: $r')
// オプショナルの処理
result := safe_divide(10, 2) or {
println('Error: $err')
0.0
}
println(result)
println(sum(1, 2, 3, 4, 5)) // 15
}
構造体
struct Person {
name string
age int
mut:
email string // 可変フィールド
}
// メソッド
fn (p Person) greet() string {
return 'Hello, my name is $p.name'
}
fn (mut p Person) have_birthday() {
p.age++
}
fn (mut p Person) update_email(new_email string) {
p.email = new_email
}
fn main() {
mut person := Person{
name: 'Alice'
age: 30
email: 'alice@example.com'
}
println(person.greet())
person.have_birthday()
println('Age: $person.age') // 31
person.update_email('newalice@example.com')
println('Email: $person.email')
}
// 構造体の埋め込み(継承のような機能)
struct Employee {
Person
employee_id string
department string
}
fn main() {
employee := Employee{
Person: Person{
name: 'Bob'
age: 28
email: 'bob@company.com'
}
employee_id: 'E001'
department: 'Engineering'
}
// 埋め込まれたフィールドに直接アクセス可能
println(employee.name) // Bob
println(employee.greet())
}
インターフェース
interface Animal {
name string
speak() string
}
struct Dog {
name string
}
fn (d Dog) speak() string {
return 'Woof!'
}
struct Cat {
name string
}
fn (c Cat) speak() string {
return 'Meow!'
}
fn make_sound(animal Animal) {
println('$animal.name says: ${animal.speak()}')
}
fn main() {
dog := Dog{ name: 'Buddy' }
cat := Cat{ name: 'Whiskers' }
make_sound(dog) // Buddy says: Woof!
make_sound(cat) // Whiskers says: Meow!
}
エラーハンドリング
Vには例外がありません。代わりに、オプショナル型とリザルト型を使用します。
import os
// オプショナル型を返す関数
fn read_file(path string) ?string {
content := os.read_file(path) or {
return error('Failed to read file: $path')
}
return content
}
// 複数のエラーを処理
fn process_data(filename string) ?[]int {
content := read_file(filename)?
lines := content.split('\n')
mut numbers := []int{}
for line in lines {
num := line.int()
numbers << num
}
return numbers
}
fn main() {
// orブロックでエラー処理
content := read_file('data.txt') or {
println('Error: $err')
return
}
println(content)
// デフォルト値を指定
backup_content := read_file('missing.txt') or { 'default content' }
// エラーを伝播
numbers := process_data('numbers.txt') or {
eprintln('Failed to process: $err')
return
}
println(numbers)
}
並行処理
Vは軽量スレッド(goroutines)をサポートしています。
import time
fn task(id int) {
for i in 0 .. 5 {
println('Task $id: step $i')
time.sleep(100 * time.millisecond)
}
}
fn main() {
// 並行実行
spawn task(1)
spawn task(2)
spawn task(3)
// メインスレッドが終了しないよう待機
time.sleep(1 * time.second)
}
// チャネルを使った通信
fn worker(ch chan int) {
for {
num := <-ch or { break }
println('Processing: $num')
time.sleep(100 * time.millisecond)
}
}
fn main() {
ch := chan int{cap: 10}
// ワーカーを起動
spawn worker(ch)
spawn worker(ch)
// データを送信
for i in 0 .. 10 {
ch <- i
}
// チャネルを閉じる
ch.close()
time.sleep(2 * time.second)
}
モジュールとパッケージ
// mymath/mymath.v
module mymath
pub fn add(a int, b int) int {
return a + b
}
pub fn multiply(a int, b int) int {
return a * b
}
fn private_function() {
// モジュール内でのみ使用可能
}
使用例:
// main.v
import mymath
fn main() {
println(mymath.add(5, 3))
println(mymath.multiply(4, 7))
}
実践例: HTTPサーバー
import vweb
struct App {
vweb.Context
}
fn main() {
vweb.run<App>(8080)
}
pub fn (mut app App) index() vweb.Result {
return app.text('Hello, V Web!')
}
['/api/users/:id']
pub fn (mut app App) get_user() vweb.Result {
id := app.params['id']
return app.json('{"id": "$id", "name": "User $id"}')
}
[post; '/api/users']
pub fn (mut app App) create_user() vweb.Result {
// リクエストボディを処理
return app.json('{"status": "created"}')
}
まとめ
V言語は、シンプルさと高速性を両立した魅力的なプログラミング言語です。学習コストが低く、C並みのパフォーマンスを発揮するため、システムプログラミングからWebアプリケーション開発まで幅広く活用できます。
まだ発展途上の言語ですが、活発なコミュニティと継続的な改善により、今後さらに成熟していくことが期待されます。