Basics of Go
- Variables and Constants:
package main
import "fmt"
func main() {
var message string = "Hello, Go!"
fmt.Println(message)
const pi = 3.14159
fmt.Println(pi)
}
- Data Types and Type Conversion:
package main
import "fmt"
func main() {
var age int = 25
fmt.Println(age)
var price float64 = 9.99
fmt.Println(price)
var isTrue bool = true
fmt.Println(isTrue)
var name string = "John"
fmt.Println(name)
// Type conversion
var num int = 42
var result float64 = float64(num)
fmt.Println(result)
}
Operators
package main
import "fmt"
func main() {
var a = 10
var b = 5
fmt.Println(a + b)
fmt.Println(a - b)
fmt.Println(a * b)
fmt.Println(a / b)
fmt.Println(a % b)
var isTrue = true
fmt.Println(!isTrue)
}
Control Structures: if-else and switch:
package main
import "fmt"
func main() {
var num = 5
if num > 0 {
fmt.Println("Number is positive")
} else if num < 0 {
fmt.Println("Number is negative")
} else {
fmt.Println("Number is zero")
}
var day = "Monday"
switch day {
case "Monday":
fmt.Println("It's Monday")
case "Tuesday":
fmt.Println("It's Tuesday")
default:
fmt.Println("It's another day")
}
}
Loops: for and range
package main
import "fmt"
func main() {
// For loop
for i := 1; i <= 5; i++ {
fmt.Println(i)
}
// Range loop
nums := []int{1, 2, 3, 4, 5}
for index, value := range nums {
fmt.Println(index, value)
}
}
Functions in Go
- Simple Function:
package main
import "fmt"
func add(a, b int) int {
return a + b
}
func main() {
result := add(3, 5)
fmt.Println(result)
}
- Function with Multiple Return Values:
package main
import "fmt"
func divide(a, b int) (int, int) {
quotient := a / b
remainder := a % b
return quotient, remainder
}
func main() {
q, r := divide(10, 3)
fmt.Println("Quotient:", q)
fmt.Println("Remainder:", r)
}
- Variadic Function:
package main
import "fmt"
func sum(numbers ...int) int {
total := 0
for _, num := range numbers {
total += num
}
return total
}
func main() {
result := sum(1, 2, 3, 4, 5)
fmt.Println(result)
}
- Anonymous Functions and Closures:
package main
import "fmt"
func main() {
add := func(a, b int) int {
return a + b
}
result := add(3, 5)
fmt.Println(result)
}
- Recursion:
package main
import "fmt"
func factorial(n int) int {
if n == 0 {
return 1
}
return n * factorial(n-1)
}
func main() {
result := factorial(5)
fmt.Println(result)
}
Arrays, Slices, and Maps in Go
- Arrays:
package main
import "fmt"
func main() {
var numbers [5]int
numbers[0] = 1
numbers[1] = 2
numbers[2] = 3
numbers[3] = 4
numbers[4] = 5
fmt.Println(numbers)
var matrix [3][3]int
matrix[0] = [3]int{1, 2, 3}
matrix[1] = [3]int{4, 5, 6}
matrix[2] = [3]int{7, 8, 9}
fmt.Println(matrix)
}
- Slices:
package main
import "fmt"
func main() {
numbers := []int{1, 2, 3, 4, 5}
fmt.Println(numbers)
fmt.Println(numbers[1:4]) // Slicing a slice
numbers = append(numbers, 6) // Appending an element
fmt.Println(numbers)
numbers = append(numbers[:2], numbers[3:]...) // Removing an element
fmt.Println(numbers)
}
- Maps:
package main
import "fmt"
func main() {
person := map[string]string{
"name": "John",
"age": "30",
"email": "john@example.com",
}
fmt.Println(person)
fmt.Println(person["name"])
person["city"] = "New York" // Adding a new key-value pair
fmt.Println(person)
delete(person, "age") // Removing a key-value pair
fmt.Println(person)
}
- Iterating over Slices and Maps:
package main
import "fmt"
func main() {
numbers := []int{1, 2, 3, 4, 5}
for index, value := range numbers {
fmt.Println(index, value)
}
person := map[string]string{
"name": "John",
"age": "30",
"email": "john@example.com",
}
for key, value := range person {
fmt.Println(key, ":", value)
}
}
Structs and Methods in Go
- Structs:
package main
import "fmt"
type Person struct {
name string
age int
address string
}
func main() {
person := Person{"John", 30, "New York"}
fmt.Println(person)
fmt.Println(person.name)
fmt.Println(person.age)
fmt.Println(person.address)
}
- Methods:
package main
import "fmt"
type Rectangle struct {
width float64
height float64
}
func (r Rectangle) area() float64 {
return r.width * r.height
}
func main() {
rect := Rectangle{3.0, 4.0}
fmt.Println(rect.area())
}
Packages and Error Handling in Go
- Packages:
package main
import (
"fmt"
"math"
)
func main() {
fmt.Println(math
.Sqrt(16))
}
- Error Handling with
errorType:
package main
import (
"fmt"
"math"
)
func calculateSqrt(num float64) (float64, error) {
if num < 0 {
return 0, fmt.Errorf("Cannot calculate square root of a negative number")
}
return math.Sqrt(num), nil
}
func main() {
result, err := calculateSqrt(-9)
if err != nil {
fmt.Println(err)
} else {
fmt.Println(result)
}
}
- Custom Error Types:
package main
import (
"fmt"
"math"
)
type NegativeNumberError struct {
number float64
}
func (e NegativeNumberError) Error() string {
return fmt.Sprintf("Cannot calculate square root of a negative number: %f", e.number)
}
func calculateSqrt(num float64) (float64, error) {
if num < 0 {
return 0, NegativeNumberError{num}
}
return math.Sqrt(num), nil
}
func main() {
result, err := calculateSqrt(-9)
if err != nil {
fmt.Println(err)
} else {
fmt.Println(result)
}
}
Database Connection
- Installing and Importing Dependencies:
package main
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
)
- Establishing a Database Connection:
func main() {
// Database connection parameters
db, err := sql.Open("mysql", "username:password@tcp(localhost:3306)/database_name")
if err != nil {
panic(err)
}
defer db.Close()
// Check if the connection is successful
err = db.Ping()
if err != nil {
panic(err)
}
fmt.Println("Connected to the database!")
}
- Creating the “users” Table:
func main() {
db, err := sql.Open("mysql", "username:password@tcp(localhost:3306)/database_name")
if err != nil {
panic(err)
}
defer db.Close()
createTableQuery := `
CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50) NOT NULL,
age INT,
city VARCHAR(50),
salary FLOAT,
added_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
`
_, err = db.Exec(createTableQuery)
if err != nil {
panic(err)
}
fmt.Println("Table 'users' created successfully!")
}
- Inserting Data into the “users” Table:
func main() {
db, err := sql.Open("mysql", "username:password@tcp(localhost:3306)/database_name")
if err != nil {
panic(err)
}
defer db.Close()
insertQuery := `
INSERT INTO users (name, age, city, salary)
VALUES (?, ?, ?, ?);
`
result, err := db.Exec(insertQuery, "John Doe", 30, "New York", 5000.0)
if err != nil {
panic(err)
}
lastInsertID, err := result.LastInsertId()
if err != nil {
panic(err)
}
fmt.Println("Inserted record ID:", lastInsertID)
}
- Querying Data from the “users” Table:
func main() {
db, err := sql.Open("mysql", "username:password@tcp(localhost:3306)/database_name")
if err != nil {
panic(err)
}
defer db.Close()
selectQuery := `
SELECT id, name, age, city, salary, added_at, updated_at
FROM users;
`
rows, err := db.Query(selectQuery)
if err != nil {
panic(err)
}
defer rows.Close()
for rows.Next() {
var id int
var name string
var age int
var city string
var salary float64
var addedAt string
var updatedAt string
err := rows.Scan(&id, &name, &age, &city, &salary, &addedAt, &updatedAt)
if err != nil {
panic(err)
}
fmt.Println("ID:", id)
fmt.Println("Name:", name)
fmt.Println("Age:", age)
fmt.Println("City:", city)
fmt.Println("Salary:", salary)
fmt.Println("Added At:", addedAt)
fmt
.Println("Updated At:", updatedAt)
fmt.Println()
}
}
Go and Gin Framework
- Retrieving All Users:
func main() {
router := gin.Default()
// ...
router.GET("/users", func(c *gin.Context) {
selectQuery := `
SELECT id, name, age, city, salary, added_at, updated_at
FROM users;
`
rows, err := db.Query(selectQuery)
if err != nil {
c.JSON(500, gin.H{"error": err.Error()})
return
}
defer rows.Close()
users := []gin.H{}
for rows.Next() {
var id int
var name string
var age int
var city string
var salary float64
var addedAt string
var updatedAt string
err := rows.Scan(&id, &name, &age, &city, &salary, &addedAt, &updatedAt)
if err != nil {
c.JSON(500, gin.H{"error": err.Error()})
return
}
user := gin.H{
"id": id,
"name": name,
"age": age,
"city": city,
"salary": salary,
"added_at": addedAt,
"updated_at": updatedAt,
}
users = append(users, user)
}
c.JSON(200, users)
})
// ...
router.Run(":8080")
}
- Deleting a User:
func main() {
router := gin.Default()
// ...
router.DELETE("/users/:id", func(c *gin.Context) {
id := c.Param("id")
deleteQuery := `
DELETE FROM users
WHERE id = ?;
`
result, err := db.Exec(deleteQuery, id)
if err != nil {
c.JSON(500, gin.H{"error": err.Error()})
return
}
rowsAffected, err := result.RowsAffected()
if err != nil {
c.JSON(500, gin.H{"error": err.Error()})
return
}
if rowsAffected == 0 {
c.JSON(404, gin.H{"message": fmt.Sprintf("User with ID %s not found", id)})
} else {
c.JSON(200, gin.H{"message": fmt.Sprintf("User with ID %s deleted", id)})
}
})
// ...
router.Run(":8080")
}
- Adding a New User:
func main() {
router := gin.Default()
// ...
router.POST("/users", func(c *gin.Context) {
var user struct {
Name string `json:"name"`
Age int `json:"age"`
City string `json:"city"`
Salary float64 `json:"salary"`
}
if err := c.ShouldBindJSON(&user); err != nil {
c.JSON(400, gin.H{"error": err.Error()})
return
}
insertQuery := `
INSERT INTO users (name, age, city, salary)
VALUES (?, ?, ?, ?);
`
result, err := db.Exec(insertQuery, user.Name, user.Age, user.City, user.Salary)
if err != nil {
c.JSON(500, gin.H{"error": err.Error()})
return
}
lastInsertID, err := result.LastInsertId()
if err != nil {
c
.JSON(500, gin.H{"error": err.Error()})
return
}
c.JSON(201, gin.H{"message": fmt.Sprintf("User created with ID %d", lastInsertID)})
})
// ...
router.Run(":8080")
}
- Fetching a Single User:
func main() {
router := gin.Default()
// ...
router.GET("/users/:id", func(c *gin.Context) {
id := c.Param("id")
selectQuery := `
SELECT id, name, age, city, salary, added_at, updated_at
FROM users
WHERE id = ?;
`
row := db.QueryRow(selectQuery, id)
var user struct {
ID int `json:"id"`
Name string `json:"name"`
Age int `json:"age"`
City string `json:"city"`
Salary float64 `json:"salary"`
AddedAt string `json:"added_at"`
UpdatedAt string `json:"updated_at"`
}
err := row.Scan(&user.ID, &user.Name, &user.Age, &user.City, &user.Salary, &user.AddedAt, &user.UpdatedAt)
if err != nil {
c.JSON(500, gin.H{"error": err.Error()})
return
}
c.JSON(200, user)
})
// ...
router.Run(":8080")
}
- Updating an Existing User:
func main() {
router := gin.Default()
// ...
router.PUT("/users/:id", func(c *gin.Context) {
id := c.Param("id")
var user struct {
Name string `json:"name"`
Age int `json:"age"`
City string `json:"city"`
Salary float64 `json:"salary"`
}
if err := c.ShouldBindJSON(&user); err != nil {
c.JSON(400, gin.H{"error": err.Error()})
return
}
updateQuery := `
UPDATE users
SET name = ?, age = ?, city = ?, salary = ?
WHERE id = ?;
`
result, err := db.Exec(updateQuery, user.Name, user.Age, user.City, user.Salary, id)
if err != nil {
c.JSON(500, gin.H{"error": err.Error()})
return
}
rowsAffected, err := result.RowsAffected()
if err != nil {
c.JSON(500, gin.H{"error": err.Error()})
return
}
if rowsAffected == 0 {
c.JSON(404, gin.H{"message": fmt.Sprintf("User with ID %s not found", id)})
} else {
c.JSON(200, gin.H{"message": fmt.Sprintf("User with ID %s updated", id)})
}
})
// ...
router.Run(":8080")
}
Please make sure to replace "username", "password", and "database_name" with your actual MySQL database credentials and database name.