Created
December 2, 2022 08:07
-
-
Save lazalong/6720f9a31c4e1023e1adf37356db9994 to your computer and use it in GitHub Desktop.
Example of generics in V. Implements the V documentation skeleton about Generics
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Example of generics in V. | |
// Its taken from the quasi-complete code in the documentation | |
// https://github.com/vlang/v/blob/master/doc/docs.md#generics | |
// credit: [email protected] | |
module main | |
interface IData {} | |
struct User { | |
id int | |
name string | |
} | |
struct Post { | |
id int | |
user_id int | |
title string | |
} | |
[heap] | |
struct DB { | |
pub mut: | |
data map[string]map[int]IData // nested maps | |
} | |
pub fn new_db() DB { | |
mut db := DB{} | |
db.data = map[string]map[int]IData{} | |
return db | |
} | |
pub fn (mut db DB[T]) query_one<T>(t string, id int) T { | |
// if id in db.data[T.name] { | |
if x := db.data[T.name][id] { | |
if x is T { | |
return *x | |
} | |
} | |
// } | |
return T{} | |
} | |
/* alternative but then the none must be handled | |
pub fn (mut db DB[T]) query_one<T>(t string, id int) ?T { | |
if x := db.data[T.name][id] { | |
if x is T { | |
println('found ${id} | x: $x') | |
return *x | |
} | |
} | |
return none | |
} | |
*/ | |
pub fn (mut db DB) add<T>(data T) { | |
db.data[T.name][data.id] = IData(data) | |
} | |
struct Repo<T> { | |
mut: | |
db &DB | |
} | |
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 (mut 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) | |
} | |
pub fn (mut r Repo<T>) add<T>(data T) { | |
r.db.add(data) | |
} | |
fn main() { | |
db := new_db() | |
mut users_repo := new_repo<User>(&db) // returns Repo<User> | |
mut posts_repo := new_repo<Post>(&db) // returns Repo<Post> | |
users_repo.add(User{1, 'test'}) | |
users_repo.add(User{2, 'test2'}) | |
posts_repo.add(Post{3, 4, 'bob' }) | |
users_repo.add(User{4, 'test3'}) | |
user := users_repo.find_by_id(1)? // find_by_id<User> | |
post := posts_repo.find_by_id(6)? // find_by_id<Post> | |
println ('user 1: ${user}') | |
println ('post 3: ${post}') | |
println('User all values ${db.data['User']}') | |
println('Post all values ${db.data['Post']}') | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment