V/イディオム
表示
< V
値の初期化
[編集]構造体の初期化
[編集]Vでは構造体の初期化に短縮記法が用意されています。フィールド名と変数名が同じ場合、値の指定を省略できます。
struct User { name string age int } // 通常の初期化 name := 'Alice' user1 := User{ name: name age: 25 } // 短縮記法を使用 name := 'Alice' user2 := User{ name // nameフィールドにname変数の値が設定される age: 25 }
デフォルト値の設定
[編集]構造体フィールドのデフォルト値は構造体定義時に指定します。
struct Configuration { timeout int = 30 // デフォルト値30 host string = 'localhost' port int = 8080 } // デフォルト値を使用 config := Configuration{} assert config.timeout == 30
エラー処理
[編集]エラーの伝播
[編集]エラーを上位に伝播させる場合は!を使用します。これにより、エラーハンドリングの意図が明確になります。
fn read_config() !string { // os.read_file()は!stringを返す content := os.read_file('config.txt')! return content } fn initialize() ! { config := read_config()! // エラーを伝播 // 設定を使用した処理 }
エラーの変換
[編集]or節でエラーを別の型に変換できます。これは、より具体的なエラー情報を提供したい場合に便利です。
fn connect_to_database(url string) !Database { db := sql.connect(url) or { return error('データベース接続エラー: ${err}') } return db }
コレクション操作
[編集]配列の変換
[編集]配列の要素を変換する場合、mapメソッドを使用します。
numbers := [1, 2, 3, 4, 5] // 各要素を2倍 doubled := numbers.map(it * 2) // 文字列に変換 strings := numbers.map(it.str())
フィルタリング
[編集]条件に合う要素のみを抽出する場合、filterメソッドを使用します。
numbers := [1, 2, 3, 4, 5] // 偶数のみ抽出 even := numbers.filter(it % 2 == 0) // 特定の条件で抽出 large := numbers.filter(it > 3)
並行処理
[編集]複数の処理の待ち合わせ
[編集]複数のgoroutineの完了を待つ場合、結果を配列で受け取ります。
fn process(id int) int { time.sleep(100 * time.millisecond) return id * 2 } fn main() { mut handles := []thread int{} // 複数の処理を開始 for i in 0..3 { handles << go process(i) } // すべての結果を待機 results := handles.wait() println(results) // [0, 2, 4] }
チャネルを使用したパイプライン
[編集]チャネルを使用して、データの流れを表現できます。
fn generator(ch chan int) { for i in 0..5 { ch <- i } ch.close() } fn square(in chan int, out chan int) { for num in in { out <- num * num } out.close() } fn main() { ch1 := chan int{} ch2 := chan int{} go generator(ch1) go square(ch1, ch2) // 結果を受信 for squared in ch2 { println(squared) } }
リソース管理
[編集]自動クローズ
[編集]リソースの解放が必要な処理は、defer節で記述します。
fn process_file() ! { mut file := os.open('data.txt')! defer { file.close() } // ファイル処理 }
スコープを利用したリソース管理
[編集]一時的なリソースはブロックスコープで管理します。
fn process_data() ! { { mut temp_file := os.open('temp.txt')! defer { temp_file.close() os.rm('temp.txt') or {} } // 一時ファイルを使用した処理 } // ここでファイルが閉じられ、削除される // 後続の処理 }
型の活用
[編集]ジェネリック関数での型制約
[編集]ジェネリック関数で型パラメータに制約を設定できます。
// 数値型のみを受け付ける fn sum[arr []T T > int || f64] T { mut total := T(0) for num in arr { total += num } return total } // インターフェースを実装する型のみを受け付ける interface Stringable { to_string() string } fn print_values[items []T T > Stringable] { for item in items { println(item.to_string()) } }
Option型の活用
[編集]値が存在しない可能性がある場合は、Option型を使用します。
struct User { name string bio ?string // バイオグラフィーは省略可能 } fn get_bio(user User) string { return user.bio or { 'バイオグラフィーはまだ設定されていません' } }
テスト
[編集]テストの構造化
[編集]テストは機能単位でグループ化します。
fn test_user_creation() { user := User{ name: 'test' age: 20 } assert user.name == 'test' assert user.age == 20 } fn test_user_validation() { user := User{ name: '' age: -1 } assert !is_valid_user(user) }
テストヘルパー
[編集]よく使用するテスト用の補助関数は、別モジュールにまとめます。
module test_helpers pub fn create_test_user() User { return User{ name: 'test_user' age: 20 } } pub fn setup_test_db() !Database { db := Database{ path: ':memory:' } return db }