65 lines
1.5 KiB
Markdown
65 lines
1.5 KiB
Markdown
|
|
```v
|
|
|
|
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.
|
|
|
|
```v
|
|
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
|
|
```
|
|
|