1.5 KiB
1.5 KiB
struct Repo[T] {
db DB
}
struct User {
id int
name string
}
struct Post {
id int
user_id int
title string
body string
}
fn new_repo[T](db DB) Repo[T] {
return Repo[T]{db: db}
}
// This is a generic function. V will generate it for every type it's used with.
fn (r Repo[T]) find_by_id(id int) ?T {
table_name := T.name // in this example getting the name of the type gives us the table name
return r.db.query_one[T]('select * from ${table_name} where id = ?', id)
}
db := new_db()
users_repo := new_repo[User](db) // returns Repo[User]
posts_repo := new_repo[Post](db) // returns Repo[Post]
user := users_repo.find_by_id(1)? // find_by_id[User]
post := posts_repo.find_by_id(1)? // find_by_id[Post]
Currently generic function definitions must declare their type parameters, but in future V will infer generic type parameters from single-letter type names in runtime parameter types. This is why find_by_id can omit [T], because the receiver argument r uses a generic type T.
fn compare[T](a T, b T) int {
if a < b {
return -1
}
if a > b {
return 1
}
return 0
}
// compare[int]
println(compare(1, 0)) // Outputs: 1
println(compare(1, 1)) // 0
println(compare(1, 2)) // -1
// compare[string]
println(compare('1', '0')) // Outputs: 1
println(compare('1', '1')) // 0
println(compare('1', '2')) // -1
// compare[f64]
println(compare(1.1, 1.0)) // Outputs: 1
println(compare(1.1, 1.1)) // 0
println(compare(1.1, 1.2)) // -1