1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

Initial commit

This commit is contained in:
Alexander Medvednikov
2019-02-08 03:59:19 +01:00
parent 825419003a
commit 8dd6fb1766
9 changed files with 348 additions and 2 deletions

View File

@@ -0,0 +1,35 @@
// Please share your thoughts, suggestions, questions, etc here:
// https://github.com/vlang-io/V/issues/3
// I'm very interested in your feedback.
import http
import json
import runtime
struct Story {
title string
}
// Fetches top HN stories in 8 coroutines
fn main() {
resp := http.get('https://hacker-news.firebaseio.com/v0/topstories.json')?
ids := json.decode([]int, resp.body)?
mut cursor := 0
for _ in 0..8 {
go fn() {
for {
lock { // Without this lock the program will not compile
if cursor >= ids.len {
break
}
id := ids[cursor]
cursor++
}
url := 'https://hacker-news.firebaseio.com/v0/item/$id.json'
resp := http.get(url)?
story := json.decode(Story, resp.body)?
println(story.title)
}
}()
}
runtime.wait() // Waits for all coroutines to finish
}

View File

@@ -0,0 +1,42 @@
// Please share your thoughts, suggestions, questions, etc here:
// https://github.com/vlang-io/V/issues/3
// I'm very interested in your feedback.
module main
struct User { /* ... */ }
struct Post { /* ... */ }
struct DB { /* ... */ }
struct Repo <T> {
db DB
}
// Generic code is notoriously verbose. To reduce clutter, V doesn't require you
// to add `<T>` every time, since it already knows that Repo is a generic type.
fn new_repo<T>(db DB) Repo {
return Repo<T>{db: db}
}
// This is a generic function. V will generate it for every type it's used with.
fn (r Repo) find_by_id(id int) T? { // `?` means the function returns an optional
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)
}
fn main() {
db := new_db()
users_repo := new_repo<User>(db)
// I'm also considering passing the type as an argument
// users_repo := new_repo(User, db)
posts_repo := new_repo<Post>(db)
user := users_repo.find_by_id(1) or {
eprintln('User not found')
return
}
post := posts_repo.find_by_id(1) or {
eprintln('Post not found')
return
}
}

View File

@@ -0,0 +1,42 @@
// Please share your thoughts, suggestions, questions, etc here:
// https://github.com/vlang-io/V/issues/3
// I'm very interested in your feedback.
module main
import ui // Native cross platform ui toolkit (uses Cocoa, win32, GTK+)
// There are no globals, so we have to use a context struct
struct Context {
input ui.TextBox // this uses native controls (NSTextView on macOS, edit HWND on Windows)
names []string // let's log the names to demonstrate how arrays work
}
fn main() {
wnd := ui.new_window(ui.WindowCfg{ // V has no default arguments and overloading.
width: 600 // All stdlib functions with many args use Cfg wrappers.
height: 300
title: 'hello world'
})
ctx := Context{
input: ui.new_textbox(wnd)
// we don't need to initialize the names array, it's done automatically
}
ctx.input.set_placeholder('Enter your name')
btn := ui.new_button(wnd, 'Click me', ctx.btn_click)
for {
ui.wait_events()
}
}
fn (ctx mut Context) btn_click() {
name := ctx.input.text()
ctx.input.hide()
println('current list of names: $ctx.names') // >> current list of names: [ "Bob", "Alex" ]
ui.alert('Hello, $name!')
if ctx.names.contains(name) {
ui.alert('I already greeted you ;)')
}
ctx.names << name
}

73
examples/users.v Normal file
View File

@@ -0,0 +1,73 @@
// Please share your thoughts, suggestions, questions, etc here:
// https://github.com/vlang-io/V/issues/3
// I'm very interested in your feedback.
module main
import json // V will automatically insert missing imports (like the goimports tool)
import http
// Right now V requires all consts to be uppercase.
// I'm still not certain about this.
const API_URL = 'https://vlang.io/users.json'
// V will generate json.encode and json.decode functions for this type since
// `json.decode([]User, ...)` is called later. This results in better
// performance, since reflection is not used.
struct User {
name string // V will automatically format and align your code.
age int // No need to use an additional tool.
is_registered bool
}
fn main() {
// `http.get()` returns an optional string.
// V optionals combine the features of Rust's Option<T> and Result<T>.
// We must unwrap all optionals with `or`, otherwise V will complain.
s := http.get(API_URL) or {
// `err` is a reserved variable (not a global) that
// contains an error message if there is one
eprintln('Failed to fetch "users.json": $err')
// `or` blocks must end with `return`, `break`, or `continue`
return
}
// Types can be passed as arguments
users := json.decode([]User, s) or {
eprintln('Failed to parse users.json')
return
}
// Encoding JSON doesn't require a type, since V knows what type
// the variable `users` has
println(json.encode(users))
// Please note the difference between V and Go:
// when there's only one variable, it's a value, not an index.
for user in users {
println('$user.name: $user.age')
}
// `for` loop has an alternative form when an index is required:
for i, user in users {
println('$i) $user')
if !user.can_register() {
// V allows both ' and " to denote strings.
// However, for consistency V will replace " with '
// unless the string contains an apostrophe.
println("Can't register")
}
}
}
// The method declaration is the same as in Go.
// There is one big difference. Here `u` can be either passed by value (User)
// or by reference (&User). The compiler will make the right decision
// depending on the size of the User struct. You no longer have to remember
// which one to use. It works here because `u` can't be modified (it's not
// marked as `mut`).
fn (u User) can_register() bool {
return u.age >= 16
}
// Here `u` can be modified and it will always be a reference.
fn (u mut User) register() {
u.is_registered = true
}