first commit
This commit is contained in:
@@ -0,0 +1,415 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'; style-src 'self'; font-src 'self' data:; img-src 'self' data:; connect-src 'self'; base-uri 'self'; form-action 'self' https://defcon.social https://bsky.app;">
|
||||
<meta http-equiv="X-Content-Type-Options" content="nosniff">
|
||||
<link rel="stylesheet" href="../assets/css/style.css">
|
||||
<link rel="icon" type="image/x-icon" href="../favicon.ico">
|
||||
<script>
|
||||
// Apply theme immediately to prevent flash
|
||||
(function() {
|
||||
const theme = localStorage.getItem('theme') ||
|
||||
(window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
|
||||
document.documentElement.setAttribute('data-theme', theme);
|
||||
})();
|
||||
</script>
|
||||
<title>Odin Quickstart Reference - Quick Reference - Launch Pad</title>
|
||||
</head>
|
||||
<body>
|
||||
<button class="theme-toggle" id="themeToggle" aria-label="Toggle dark mode">
|
||||
<svg class="theme-icon theme-icon-moon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path></svg>
|
||||
<svg class="theme-icon theme-icon-sun" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="display: none;"><circle cx="12" cy="12" r="5"></circle><line x1="12" y1="1" x2="12" y2="3"></line><line x1="12" y1="21" x2="12" y2="23"></line><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line><line x1="1" y1="12" x2="3" y2="12"></line><line x1="21" y1="12" x2="23" y2="12"></line><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line></svg>
|
||||
</button>
|
||||
<br/><br/>
|
||||
<div class="name">
|
||||
__ _______________________ _________._________________________
|
||||
\_ _____/ \______ \ / _ \ / _____/ / _____/ | | \_ _____/
|
||||
| __) | _/ / /_\ \ / \ ___ / \ ___ | | | __)_
|
||||
| \ | | \ / | \ \ \_\ \ \ \_\ \ | |___ | \
|
||||
\___ / |____|_ / \____|__ / \______ / \______ / |_______ \ /_______ /
|
||||
\/ \/ \/ \/ \/ \/ \/
|
||||
</div>
|
||||
<div class="blog-page-header">
|
||||
<div class="blog-header-content">
|
||||
<a href="/quickref" class="back-link" title="Back to Quick Reference">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="42" height="42" viewBox="0 0 24 24" class="home-icon"><path fill="currentColor" d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/></svg>
|
||||
</a>
|
||||
<h1 class="blog-page-title">Odin Quickstart Reference</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="blog-post-container">
|
||||
<div class="blog-posts-container" style="max-width: 900px; margin: 0 auto;">
|
||||
<div class="blog-post">
|
||||
<div class="blog-post-content">
|
||||
<p><a href="index.html">← Back to quick reference</a></p>
|
||||
<p><a href="../index.html">← Home</a></p>
|
||||
<hr>
|
||||
<p>Quick reference guide for Odin. Essential syntax, types, control flow, and common patterns for the Odin programming language.</p>
|
||||
<hr>
|
||||
<h2>Hello World</h2>
|
||||
<pre><code>package main
|
||||
|
||||
import "core:fmt"
|
||||
|
||||
main :: proc() {
|
||||
fmt.println("Hello, World!") // Odin keeps it clean and readable.
|
||||
}</code></pre>
|
||||
<hr>
|
||||
<h2>Variables</h2>
|
||||
<pre><code>x: int = 42
|
||||
name: string = "Alice"
|
||||
flag: bool = true
|
||||
pi: f64 = 3.14
|
||||
|
||||
// Type inference with :=
|
||||
y := 100 // Compiler infers int
|
||||
text := "Hello" // Compiler infers string
|
||||
|
||||
// Multiple declarations
|
||||
a, b, c: int = 1, 2, 3
|
||||
</code></pre>
|
||||
<hr>
|
||||
<h2>Control Flow</h2>
|
||||
<h3>If/Else</h3>
|
||||
<pre><code>if x > 10 {
|
||||
fmt.println("x is big")
|
||||
} else {
|
||||
fmt.println("x is small")
|
||||
}
|
||||
|
||||
if x > 10 {
|
||||
fmt.println("big")
|
||||
} else if x > 5 {
|
||||
fmt.println("medium")
|
||||
} else {
|
||||
fmt.println("small")
|
||||
}
|
||||
|
||||
// If as expression
|
||||
result := "big" if x > 10 else "small"
|
||||
</code></pre>
|
||||
<h3>For Loops</h3>
|
||||
<pre><code>for i in 0..5 { // 0 to 4, exclusive
|
||||
fmt.println(i)
|
||||
}
|
||||
|
||||
for i in 0..=5 { // 0 to 5, inclusive
|
||||
fmt.println(i)
|
||||
}
|
||||
|
||||
nums := []int{1, 2, 3}
|
||||
for n in nums {
|
||||
fmt.println(n)
|
||||
}
|
||||
|
||||
for n, i in nums { // Value and index
|
||||
fmt.printf("%d: %d\n", i, n)
|
||||
}
|
||||
|
||||
// Traditional C-style
|
||||
for i := 0; i < 5; i += 1 {
|
||||
fmt.println(i)
|
||||
}
|
||||
</code></pre>
|
||||
<h3>While Loops</h3>
|
||||
<pre><code>y := 10
|
||||
for y > 0 {
|
||||
y -= 1
|
||||
fmt.println(y)
|
||||
}
|
||||
|
||||
// Infinite loop
|
||||
for {
|
||||
if y <= 0 {
|
||||
break
|
||||
}
|
||||
y -= 1
|
||||
}
|
||||
</code></pre>
|
||||
<hr>
|
||||
<h2>Functions</h2>
|
||||
<pre><code>add := fn(a: int, b: int) -> int {
|
||||
return a + b
|
||||
}
|
||||
|
||||
fmt.println(add(2, 3))
|
||||
|
||||
// Named function
|
||||
add :: proc(a: int, b: int) -> int {
|
||||
return a + b
|
||||
}
|
||||
|
||||
// Multiple return values
|
||||
divide :: proc(a: f64, b: f64) -> (f64, bool) {
|
||||
if b == 0 {
|
||||
return 0, false
|
||||
}
|
||||
return a / b, true
|
||||
}
|
||||
|
||||
result, ok := divide(10.0, 2.0)
|
||||
if ok {
|
||||
fmt.println(result)
|
||||
}
|
||||
|
||||
// Procedures (no return value)
|
||||
greet :: proc(name: string) {
|
||||
fmt.printf("Hello, %s!\n", name)
|
||||
}
|
||||
</code></pre>
|
||||
<hr>
|
||||
<h2>Arrays / Slices</h2>
|
||||
<h3>Slices</h3>
|
||||
<pre><code>nums: []int = [1, 2, 3] // Slice literal, mutable and resizable
|
||||
for n in nums {
|
||||
fmt.println(n)
|
||||
}
|
||||
|
||||
// Append to slice
|
||||
append(&nums, 4)
|
||||
append(&nums, 5, 6)
|
||||
|
||||
// Length and capacity
|
||||
len(nums) // Current length
|
||||
cap(nums) // Capacity
|
||||
|
||||
// Make slice with capacity
|
||||
nums := make([]int, 0, 10) // Length 0, capacity 10
|
||||
</code></pre>
|
||||
<h3>Arrays</h3>
|
||||
<pre><code>arr: [3]int = {1, 2, 3} // Fixed-size array
|
||||
arr := [3]int{1, 2, 3} // Shorthand
|
||||
|
||||
// Array size inference
|
||||
arr := [?]int{1, 2, 3} // Compiler infers size 3
|
||||
</code></pre>
|
||||
<h3>Maps</h3>
|
||||
<pre><code>import "core:map"
|
||||
|
||||
person := make(map[string]string)
|
||||
map.set(&person, "name", "Alice")
|
||||
map.set(&person, "age", "30")
|
||||
|
||||
name, found := map.get(&person, "name")
|
||||
if found {
|
||||
fmt.println(name)
|
||||
}
|
||||
|
||||
// Map literal
|
||||
person := map[string]string{
|
||||
"name" = "Alice",
|
||||
"age" = "30",
|
||||
}
|
||||
</code></pre>
|
||||
<hr>
|
||||
<h2>Strings</h2>
|
||||
<pre><code>text := "Hello, World!"
|
||||
text := `Multiline
|
||||
string
|
||||
literal`
|
||||
|
||||
// String operations
|
||||
len(text) // Length in bytes
|
||||
fmt.printf("%s\n", text) // Print formatted
|
||||
|
||||
// String concatenation
|
||||
greeting := "Hello, " + name
|
||||
|
||||
// String formatting
|
||||
name := "Alice"
|
||||
greeting := fmt.tprintf("Hello, %s!", name)
|
||||
</code></pre>
|
||||
<hr>
|
||||
<h2>Structs</h2>
|
||||
<pre><code>Person :: struct {
|
||||
name: string,
|
||||
age: int,
|
||||
}
|
||||
|
||||
person := Person{
|
||||
name = "Alice",
|
||||
age = 30,
|
||||
}
|
||||
|
||||
fmt.printf("%s is %d\n", person.name, person.age)
|
||||
|
||||
// Methods
|
||||
Person :: struct {
|
||||
name: string,
|
||||
age: int,
|
||||
}
|
||||
|
||||
greet :: proc(p: Person) {
|
||||
fmt.printf("Hello, I'm %s\n", p.name)
|
||||
}
|
||||
|
||||
person := Person{name = "Alice", age = 30}
|
||||
greet(person)
|
||||
</code></pre>
|
||||
<hr>
|
||||
<h2>Enums</h2>
|
||||
<pre><code>Direction :: enum {
|
||||
Up,
|
||||
Down,
|
||||
Left,
|
||||
Right,
|
||||
}
|
||||
|
||||
dir := Direction.Up
|
||||
|
||||
switch dir {
|
||||
case .Up:
|
||||
fmt.println("Going up")
|
||||
case .Down:
|
||||
fmt.println("Going down")
|
||||
case .Left:
|
||||
fmt.println("Going left")
|
||||
case .Right:
|
||||
fmt.println("Going right")
|
||||
}
|
||||
</code></pre>
|
||||
<hr>
|
||||
<h2>Unions</h2>
|
||||
<pre><code>Value :: union {
|
||||
int,
|
||||
f64,
|
||||
string,
|
||||
}
|
||||
|
||||
v: Value = 42
|
||||
v = 3.14
|
||||
v = "hello"
|
||||
|
||||
switch v in v {
|
||||
case int:
|
||||
fmt.printf("Integer: %d\n", v)
|
||||
case f64:
|
||||
fmt.printf("Float: %f\n", v)
|
||||
case string:
|
||||
fmt.printf("String: %s\n", v)
|
||||
}
|
||||
</code></pre>
|
||||
<hr>
|
||||
<h2>Error Handling</h2>
|
||||
<pre><code>import "core:fmt"
|
||||
|
||||
// Using optional types
|
||||
divide :: proc(a: f64, b: f64) -> (result: f64, ok: bool) {
|
||||
if b == 0 {
|
||||
return 0, false
|
||||
}
|
||||
return a / b, true
|
||||
}
|
||||
|
||||
result, ok := divide(10.0, 2.0)
|
||||
if ok {
|
||||
fmt.printf("Result: %f\n", result)
|
||||
} else {
|
||||
fmt.println("Division by zero")
|
||||
}
|
||||
|
||||
// Using error types
|
||||
Error :: enum {
|
||||
None,
|
||||
Division_By_Zero,
|
||||
Invalid_Input,
|
||||
}
|
||||
|
||||
divide :: proc(a: f64, b: f64) -> (f64, Error) {
|
||||
if b == 0 {
|
||||
return 0, .Division_By_Zero
|
||||
}
|
||||
return a / b, .None
|
||||
}
|
||||
</code></pre>
|
||||
<hr>
|
||||
<h2>File Operations</h2>
|
||||
<pre><code>import "core:os"
|
||||
import "core:fmt"
|
||||
|
||||
// Reading
|
||||
data, ok := os.read_entire_file("file.txt")
|
||||
if ok {
|
||||
fmt.println(string(data))
|
||||
}
|
||||
|
||||
// Writing
|
||||
content := "Hello, World!"
|
||||
os.write_entire_file("file.txt", transmute([]u8)content)
|
||||
</code></pre>
|
||||
<hr>
|
||||
<h2>Memory Management</h2>
|
||||
<pre><code>import "core:mem"
|
||||
|
||||
// Allocators
|
||||
allocator := context.allocator
|
||||
|
||||
// Allocate memory
|
||||
ptr := new(int)
|
||||
ptr^ = 42
|
||||
|
||||
// Free memory
|
||||
free(ptr)
|
||||
|
||||
// Using different allocators
|
||||
temp_allocator := mem.temp_allocator()
|
||||
</code></pre>
|
||||
<hr>
|
||||
<h2>Tips</h2>
|
||||
<ul>
|
||||
<li>Odin is strongly typed; type declarations are explicit.</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>Loops often use ranges like <code>0..5</code> (exclusive of 5); use <code>0..=5</code> for inclusive.</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><code>fmt.scanf</code> or <code>read_string</code> can handle user input:
|
||||
<pre><code>import "core:fmt"
|
||||
import "core:os"
|
||||
|
||||
input: [256]u8
|
||||
n, _ := os.read(os.stdin, input[:])
|
||||
text := string(input[:n])</code></pre>
|
||||
</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>Slices (<code>[]Type</code>) are dynamic arrays, arrays (<code>[N]Type</code>) are fixed-size.</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>Functions are first-class and can be assigned to variables.</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>Use <code>:=</code> for type inference, <code>:</code> for explicit typing.</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>Procedures (<code>proc</code>) are functions; use <code>fn</code> for function values.</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>Multiple return values are common; use tuples or named returns.</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>Use <code>^</code> to dereference pointers, <code>&</code> to take addresses.</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>Odin uses explicit memory management; understand allocators for advanced usage.</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>Struct literals use <code>=</code> for field assignment: <code>Person{name = "Alice"}</code>.</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>Use <code>switch</code> for pattern matching on enums and unions.</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>Import packages with <code>import "package:name"</code>; core library uses <code>"core:"</code> prefix.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script async type="text/javascript" src="../blog/analytics.js"></script>
|
||||
<script src="../theme.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user