《Go 简易速速上手小册》第1章:Go 语言基础(2024 最新版)

在这里插入图片描述

文章目录

  • 1.1 Go 语言的安装与环境配置
    • 1.1.1 基础知识讲解
      • 案例 Demo:简单的 Go 程序
    • 1.1.2 重点案例:搭建一个 Go Web 服务
      • 准备工作
      • 步骤 1:创建项目目录
      • 步骤 2:编写 Web 服务代码
      • 步骤 3:运行你的 Web 服务
      • 步骤 4:测试服务
    • 1.1.3 拓展案例 1:使用 Go 连接数据库
      • 准备工作
      • 步骤 1:编写 Go 程序连接数据库
      • 步骤 2:运行程序
    • 1.1.3 拓展案例 2:创建一个 RESTful API
      • 准备工作
      • 步骤 1:创建项目目录
      • 步骤 2:编写 RESTful API 代码
      • 步骤 3:运行你的 API
      • 步骤 4:测试 API
  • 1.2 基本语法介绍
    • 1.2.1 基础知识讲解
    • 1.2.2 重点案例:计算字符串中字母的出现频率
      • 基本实现
      • 案例扩展
        • **步骤 1:读取文件**
        • **步骤 2:整合到主程序中**
        • **如何运行**
    • 1.2.3 拓展案例 1:斐波那契数列
      • 基本实现
      • 迭代实现
      • 性能比较
      • 使用 `sync.Map` 缓存结果
    • 1.2.4 拓展案例 2:简单的 Web 服务器
      • 基本 Web 服务器
      • 扩展案例:处理静态文件
      • 扩展案例:动态内容生成
      • 结论
  • 1.3 变量和类型
    • 1.3.1 基础知识讲解
    • 1.3.2 重点案例:处理温度转换
      • 扩展功能
      • 实现代码
      • 使用说明
    • 1.3.3 拓展案例 1:货币转换
      • 实现代码
      • 使用说明
    • 1.3.4 拓展案例 2:字符串处理
      • 实现代码
      • 使用说明

第1章:Go 语言基础

1.1 Go 语言的安装与环境配置

在开始 Go 语言的旅程之前,我们首先需要搭建一个舒适的环境,让 Go 能在你的机器上愉快地运行。这就像是为一场盛大的宴会做准备,确保每位嘉宾(Go 程序)都能找到它们的座位(运行环境),并享用美食(系统资源)。

1.1.1 基础知识讲解

下载 Go

首先,你需要前往 Go 语言的官方网站下载安装包。这个网站像是 Go 语言的家,你可以在这里找到最新版本的 Go。确保选择与你的操作系统相匹配的版本。如果你是 Windows 用户,就下载 Windows 版;如果你使用的是 macOS 或 Linux,相应地选择那个版本。

安装 Go

下载完成后,启动安装程序。安装 Go 语言就像是在你的计算机上安装一个游戏,跟随安装向导一步一步来,不需要做特别的配置。安装向导会将 Go 安装在默认的位置,并且配置好所有必需的环境变量。在这个过程中,你可以喝一杯咖啡,享受一下等待的时光。

配置环境变量

  • GOPATH:这是 Go 语言的工作空间,你的 Go 项目和第三方库会存放在这里。想象一下,这就像是你的工作桌,你所有的工具和文件都在这个地方。
  • GOROOT:这是 Go 语言安装的位置,大多数时候,你不需要手动设置这个变量,除非你想要将 Go 安装在一个非标准的位置。
  • PATH:为了能够在任何地方通过命令行运行 Go 程序,你需要把 Go 的 bin 目录添加到 PATH 环境变量中。这就像是在告诉你的计算机,你安装的 Go 程序在哪里,它可以去那里找到它们。

验证安装

打开终端或命令提示符,输入 go version。如果看到了 Go 的版本号,那么恭喜你,你已经成功安装了 Go 语言。这就像是通过了编程世界的入学考试,你现在准备好了接受更多的挑战。

案例 Demo:简单的 Go 程序

为了让你更好地理解如何开始使用 Go,让我们来编写一个简单的程序,这个程序会打印出“Hello, Go!”。这是每个编程语言学习者的传统,也是你的第一个里程碑。

  1. 创建文件
    在你的工作目录(GOPATH)中,创建一个新的文件夹 hello-go,然后在这个文件夹中创建一个名为 main.go 的文件。

  2. 编写代码
    使用文本编辑器打开 main.go 文件,然后输入以下代码:

    package main
    
    import "fmt"
    
    func main() {
        fmt.Println("Hello, Go!")
    }
    

    这段代码的作用是引入 Go 语言的标准库 fmt,并在 main 函数中调用 fmt.Println 函数来在屏幕上打印出 “Hello, Go!”。

  3. 运行程序
    在命令行中,导航到 hello-go 文件夹的位置,然后输入命令 go run main.go。你的屏幕上应该会显示 “Hello, Go!” 的字样。

恭喜你,你刚刚完成了你的第一个 Go 程序!这是一个简单但重要的开始,你已经迈出了成为 Go 开发者之旅的第一步。随着你继续深入学习,你将会发现 Go 语言的强大之处,并开始构建更复杂的应用程序。

1.1.2 重点案例:搭建一个 Go Web 服务

现在,让我们深入实践,通过创建一个简单的 Go Web 服务来进一步探索 Go 语言。这个 Web 服务将监听 HTTP 请求,并返回一个欢迎消息。这不仅是一个绝佳的实践机会,也能让你体验到使用 Go 构建网络应用的简便与强大。

准备工作

在开始之前,确保你已经按照前面的指导安装了 Go,并且能够在命令行中运行 go version 命令。

步骤 1:创建项目目录

在你的 GOPATH 下,创建一个新的目录用于本项目,我们将其命名为 hello-web。这将是我们项目的根目录。

步骤 2:编写 Web 服务代码

  1. hello-web 目录中,创建一个新的文件,命名为 main.go
  2. 使用文本编辑器打开 main.go 文件,并写入以下代码:
package main

import (
    "fmt"
    "net/http"
)

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "欢迎来到 Go Web 服务!")
    })

    fmt.Println("服务启动,监听端口 8080")
    if err := http.ListenAndServe(":8080", nil); err != nil {
        fmt.Println("服务器启动失败:", err)
    }
}

这段代码做了什么?

  • 定义了一个简单的 HTTP 服务器。
  • 使用 http.HandleFunc 注册了一个处理函数,当访问根路径 / 时,将执行这个函数。
  • 在函数中,我们向响应写入了 “欢迎来到 Go Web 服务!”。
  • 最后,我们告诉 HTTP 服务器监听 8080 端口,并启动服务。

步骤 3:运行你的 Web 服务

  1. 打开命令行工具,切换到项目目录 hello-web
  2. 输入命令 go run main.go 来启动你的 Web 服务。
  3. 你应该能看到输出 “服务启动,监听端口 8080”,这表示你的 Web 服务已经在运行了。

步骤 4:测试服务

  1. 打开你的 Web 浏览器。
  2. 在地址栏中输入 http://localhost:8080,然后按 Enter 键。
  3. 你的浏览器应该显示 “欢迎来到 Go Web 服务!”。

恭喜你!你已经成功创建并运行了你的第一个 Go Web 服务。通过这个简单的例子,你不仅学会了如何使用 Go 语言来开发 Web 应用,还体验到了 Go 在网络编程方面的强大和简洁。随着你继续深入学习,你将能够开发更加复杂和功能丰富的 Web 应用。

1.1.3 拓展案例 1:使用 Go 连接数据库

在现实世界的应用中,Web 服务经常需要与数据库进行交互来存储和检索数据。Go 语言通过其标准库 database/sql 以及数据库特定的驱动程序,提供了一个简单而强大的方式来连接和操作数据库。本案例将展示如何使用 Go 连接到 PostgreSQL 数据库,并执行一个简单的查询。

准备工作

  • 确保你已经安装了 PostgreSQL 数据库,并且数据库正在运行。
  • 创建一个数据库和表用于测试。例如,我们创建一个名为 testdb 的数据库,以及一个名为 users 的表:
CREATE DATABASE testdb;

CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    name TEXT NOT NULL,
    email TEXT NOT NULL
);
  • users 表中插入一些示例数据:
INSERT INTO users (name, email) VALUES ('Alice', 'alice@example.com');
INSERT INTO users (name, email) VALUES ('Bob', 'bob@example.com');
  • 安装 PostgreSQL 的 Go 驱动。在命令行中运行以下命令:
go get -u github.com/lib/pq

这将安装 pq 驱动,这是一个实现了 database/sql 接口的 PostgreSQL 驱动。

步骤 1:编写 Go 程序连接数据库

  1. 在你的项目目录中(可以复用之前的 hello-web 目录或创建一个新的),创建一个新的文件,命名为 main.go
  2. 编辑 main.go 文件,写入以下代码:
package main

import (
    "database/sql"
    "fmt"
    "log"

    _ "github.com/lib/pq"
)

const (
    host     = "localhost"
    port     = 5432 // PostgreSQL 默认端口
    user     = "你的用户名"
    password = "你的密码"
    dbname   = "testdb"
)

func main() {
    // 构建连接字符串
    psqlInfo := fmt.Sprintf("host=%s port=%d user=%s "+
        "password=%s dbname=%s sslmode=disable",
        host, port, user, password, dbname)

    // 连接数据库
    db, err := sql.Open("postgres", psqlInfo)
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()

    // 测试数据库连接
    err = db.Ping()
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println("成功连接到数据库")

    // 执行查询
    sqlStatement := `SELECT id, name, email FROM users;`
    rows, err := db.Query(sqlStatement)
    if err != nil {
        log.Fatal(err)
    }
    defer rows.Close()

    // 遍历查询结果
    for rows.Next() {
        var id int
        var name, email string
        err = rows.Scan(&id, &name, &email)
        if err != nil {
            log.Fatal(err)
        }
        fmt.Printf("ID: %d, Name: %s, Email: %s\n", id, name, email)
    }

    // 检查查询过程中是否有错误发生
    err = rows.Err()
    if err != nil {
        log.Fatal(err)
    }
}

这段代码做了什么?

  • 定义了数据库连接的参数,并构建了一个连接字符串。
  • 使用 sql.Open 连接到 PostgreSQL 数据库。
  • 使用 db.Ping() 测试连接是否成功。
  • 执行了一个 SQL 查询,选择 users 表中的所有记录,并遍历这些记录。
  • 使用 rows.Scan 将每条记录的字段值赋值给相应的变量。

步骤 2:运行程序

  1. 确保你已经根据实际情况修改了数据库连接参数。
  2. 在命令行中,运行 go run main.go
  3. 如果一切顺利,你将看到成功连接到数据库的消息,以及 users 表中的记录被打印到终端。

通过这个案例,你已经学会了如何在 Go 程序中连接并操作 PostgreSQL 数据库。这是开发现代 Web 应用中一个非常重要的技能。随着你对 Go 和数据库编程的进一步学习,你将能够构建更加复杂和强大的数据驱动应用。

1.1.3 拓展案例 2:创建一个 RESTful API

在这个案例中,我们将使用 Go 语言创建一个简单的 RESTful API。这个 API 将能够处理 HTTP GET 请求,并返回一个 JSON 格式的响应。我们将构建一个用户信息服务,当请求 /users 路径时,它会返回用户列表的 JSON 数据。

准备工作

确保你已经安装了 Go,并且你的开发环境已经设置好。

步骤 1:创建项目目录

在你的 GOPATH 下,创建一个新的目录用于本项目,我们将其命名为 rest-api。这将是我们项目的根目录。

步骤 2:编写 RESTful API 代码

  1. rest-api 目录中,创建一个新的文件,命名为 main.go
  2. 使用文本编辑器打开 main.go 文件,并写入以下代码:
package main

import (
    "encoding/json"
    "net/http"
)

// User 定义了用户信息的结构体
type User struct {
    ID   int    `json:"id"`
    Name string `json:"name"`
    Email string `json:"email"`
}

// users 列表模拟了一个简单的数据存储
var users = []User{
    {ID: 1, Name: "Alice", Email: "alice@example.com"},
    {ID: 2, Name: "Bob", Email: "bob@example.com"},
}

func getUsers(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(users)
}

func main() {
    http.HandleFunc("/users", getUsers)
    http.ListenAndServe(":8080", nil)
}

这段代码实现了什么?

  • 定义了一个 User 结构体来存储用户信息。
  • 创建了一个全局变量 users,它是 User 结构体切片,用来模拟数据存储。
  • 实现了一个 getUsers 函数,这个函数将处理所有到 /users 路径的 HTTP GET 请求。它将用户列表转换为 JSON 格式,并写入响应。
  • main 函数中,我们使用 http.HandleFunc 注册了 getUsers 函数作为 /users 路径的处理器,然后启动了 HTTP 服务器监听 8080 端口。

步骤 3:运行你的 API

  1. 打开命令行工具,切换到项目目录 rest-api
  2. 输入命令 go run main.go 来启动你的 RESTful API。
  3. 你应该能看到服务器启动,并在 8080 端口监听请求。

步骤 4:测试 API

  1. 打开你的 Web 浏览器或使用一个 HTTP 客户端工具(如 Postman 或 curl)。
  2. http://localhost:8080/users 发送一个 GET 请求。
  3. 你的请求应该会收到一个 JSON 格式的响应,内容是用户列表的数据。

通过这个案例,你已经学会了如何使用 Go 创建一个简单的 RESTful API,它能够处理 HTTP GET 请求并返回 JSON 数据。这是构建现代 Web 应用和微服务架构的基础。随着你对 Go 的进一步学习和实践,你将能够创建更复杂的 RESTful API,支持更多的 HTTP 方法和功能。

1.2 基本语法介绍

欢迎进入 Go 语言的世界!在这一节中,我们将探索 Go 语言的基本语法元素,包括变量声明、控制流程(如条件判断和循环)以及函数的定义和使用。掌握这些基础知识是成为一名 Go 程序员的关键第一步。

1.2.1 基础知识讲解

变量声明

在 Go 中,你可以使用 var 关键字来声明一个变量。Go 也支持类型推断,所以你可以用 := 语法在声明变量的同时对其进行初始化,而不必显式指定类型。

var name string = "Alice"
age := 30 // 类型推断为 int

控制流程

  • 条件判断:Go 语言使用 ifelse 关键字进行条件判断。与其他语言不同,Go 的条件判断语句不需要用括号将条件包围起来。
if age > 18 {
    fmt.Println("You are an adult.")
} else {
    fmt.Println("You are a minor.")
}
  • 循环:Go 语言中的循环使用 for 关键字。Go 没有 while 关键字,但是你可以通过 for 实现同样的功能。
for i := 0; i < 5; i++ {
    fmt.Println("Loop", i)
}

函数

在 Go 中,你可以使用 func 关键字来定义一个函数。函数可以有参数和返回值。

func greet(name string) string {
    return "Hello, " + name
}

1.2.2 重点案例:计算字符串中字母的出现频率

在文本处理、数据分析或者密码学领域,统计一个字符串中每个字母的出现频率是一项基础而常见的任务。这个案例将展示如何使用 Go 语言实现这一功能,并进一步扩展功能以提供更实用的应用场景。

基本实现

首先,我们从基本的实现开始。以下 Go 程序能够计算并打印出给定字符串中每个字母的出现次数,忽略大小写,并排除非字母字符。

package main

import (
    "fmt"
    "strings"
    "unicode"
)

func countLetters(input string) map[rune]int {
    counts := make(map[rune]int)
    for _, char := range strings.ToLower(input) {
        if unicode.IsLetter(char) {
            counts[char]++
        }
    }
    return counts
}

func main() {
    input := "Hello, Go! Gophers..."
    letterCounts := countLetters(input)
    for char, count := range letterCounts {
        fmt.Printf("%c appears %d times\n", char, count)
    }
}

案例扩展

现在,让我们将这个程序扩展为一个更实用的版本,该版本可以从文件中读取文本,计算并显示每个字母的出现频率。

步骤 1:读取文件

假设我们有一个名为 text.txt 的文件,包含了我们想要分析的文本。我们将编写代码来读取这个文件的内容。

func readFileContent(filePath string) (string, error) {
    bytes, err := ioutil.ReadFile(filePath)
    if err != nil {
        return "", err
    }
    return string(bytes), nil
}
步骤 2:整合到主程序中

现在,我们将 readFileContent 函数整合到主程序中,从而允许我们从文件中读取文本并分析字母频率。

package main

import (
    "fmt"
    "io/ioutil"
    "strings"
    "unicode"
)

func countLetters(input string) map[rune]int {
    counts := make(map[rune]int)
    for _, char := range strings.ToLower(input) {
        if unicode.IsLetter(char) {
            counts[char]++
        }
    }
    return counts
}

func readFileContent(filePath string) (string, error) {
    bytes, err := ioutil.ReadFile(filePath)
    if err != nil {
        return "", err
    }
    return string(bytes), nil
}

func main() {
    filePath := "text.txt"
    content, err := readFileContent(filePath)
    if err != nil {
        fmt.Println("Error reading file:", err)
        return
    }

    letterCounts := countLetters(content)
    for char, count := range letterCounts {
        fmt.Printf("%c appears %d times\n", char, count)
    }
}
如何运行
  1. 确保你的工作目录中有一个名为 text.txt 的文件,里面包含了你想要分析的文本。
  2. 运行上述 Go 程序。程序将读取 text.txt 文件的内容,计算每个字母的出现频率,并将结果打印到控制台。

通过这种方式,我们不仅实现了一个基本的字符串分析工具,还展示了如何处理文件输入,使得这个小程序更接近实际应用的场景。这个案例展示了 Go 语言在处理文本和文件操作方面的能力,为更复杂的文本处理和数据分析任务奠定了基础。

1.2.3 拓展案例 1:斐波那契数列

斐波那契数列是一个经典的编程问题,它展示了递归和迭代两种基本的算法思想。在这个扩展案例中,我们将探讨如何用 Go 语言实现斐波那契数列的计算,并比较递归和迭代两种方法的不同。

基本实现

首先,我们从递归实现开始。递归方法是最直观的实现方式,但它可能不是最高效的,尤其是对于较大的数字。

package main

import "fmt"

func fibonacciRecursive(n int) int {
    if n <= 1 {
        return n
    }
    return fibonacciRecursive(n-1) + fibonacciRecursive(n-2)
}

func main() {
    n := 10 // 计算斐波那契数列的第10个数字
    fmt.Printf("斐波那契数列第 %d 个数字是: %d\n", n, fibonacciRecursive(n))
}

迭代实现

虽然递归方法简单直观,但对于大数值的计算,它可能会导致堆栈溢出或者不必要的计算开销。下面是使用迭代方法计算斐波那契数列的实现,它提高了计算效率。

func fibonacciIterative(n int) int {
    if n <= 1 {
        return n
    }
    prev, curr := 0, 1
    for i := 2; i <= n; i++ {
        prev, curr = curr, prev+curr
    }
    return curr
}

func main() {
    n := 10 // 计算斐波那契数列的第10个数字
    fmt.Printf("斐波那契数列第 %d 个数字是: %d (迭代方法)\n", n, fibonacciIterative(n))
}

性能比较

对于较小的 n 值,递归和迭代方法的性能差异不明显。但随着 n 值的增大,递归方法的性能将显著下降,而迭代方法的性能基本保持稳定。这是因为递归方法在计算过程中会产生大量的重复计算,而迭代方法则避免了这种情况。

使用 sync.Map 缓存结果

对于递归方法,一种提高性能的策略是使用缓存来存储已计算的斐波那契数,避免重复计算。Go 的 sync.Map 提供了一个并发安全的方式来存储和检索键值对。

import (
    "fmt"
    "sync"
)

var cache = sync.Map{}

func fibonacciMemoization(n int) int {
    if n <= 1 {
        return n
    }
    if val, ok := cache.Load(n); ok {
        return val.(int)
    }
    val := fibonacciMemoization(n-1) + fibonacciMemoization(n-2)
    cache.Store(n, val)
    return val
}

func main() {
    n := 10
    fmt.Printf("斐波那契数列第 %d 个数字是: %d (带缓存的递归方法)\n", n, fibonacciMemoization(n))
}

通过使用缓存,我们可以显著提高递归方法计算斐波那契数的效率,尤其是对于较大的 n 值。这种方法结合了递归直观的优点和迭代高效的优点,使得算法既简洁又高效。

通过这个案例的扩展,我们展示了如何使用 Go 语言实现和优化斐波那契数列的计算。这不仅加深了对 Go 语言基础知识的理解,也提供了算法优化的实践经验。

1.2.4 拓展案例 2:简单的 Web 服务器

创建一个简单的 Web 服务器是学习 Web 开发的基础。在这个案例中,我们将使用 Go 语言扩展简单的 Web 服务器功能,包括处理静态文件和动态请求。这能够为构建更复杂的 Web 应用提供基础。

基本 Web 服务器

首先,让我们回顾如何用 Go 创建一个基本的 Web 服务器,它可以监听 HTTP 请求并返回一个简单的响应。

package main

import (
    "fmt"
    "net/http"
)

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "欢迎访问我们的首页!")
    })

    fmt.Println("服务器启动,监听端口 8080...")
    if err := http.ListenAndServe(":8080", nil); err != nil {
        fmt.Printf("启动服务器时出错: %v", err)
    }
}

扩展案例:处理静态文件

现代 Web 应用通常需要提供静态资源(如 HTML 文件、CSS 样式表、JavaScript 脚本和图片)。Go 的 http 包提供了一个方便的方式来处理静态文件。

func main() {
    // 设置静态文件处理
    fs := http.FileServer(http.Dir("static"))
    http.Handle("/static/", http.StripPrefix("/static/", fs))

    // 动态请求处理
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "欢迎访问我们的首页!")
    })

    fmt.Println("服务器启动,监听端口 8080...")
    if err := http.ListenAndServe(":8080", nil); err != nil {
        fmt.Printf("启动服务器时出错: %v", err)
    }
}

在这个例子中,我们假设有一个名为 static 的目录,它包含了所有的静态资源。我们使用 http.FileServer 创建了一个文件服务器来处理 /static/ 路径下的所有请求,使其能够返回 static 目录下的静态文件。

扩展案例:动态内容生成

除了静态文件,Web 服务器还经常需要根据请求动态生成内容。以下是一个简单的例子,展示了如何根据查询参数返回定制化的问候语。

func main() {
    http.HandleFunc("/greet", func(w http.ResponseWriter, r *http.Request) {
        name := r.URL.Query().Get("name")
        if name == "" {
            name = "Guest"
        }
        fmt.Fprintf(w, "Hello, %s!", name)
    })

    // 静态文件和首页处理省略...

    fmt.Println("服务器启动,监听端口 8080...")
    if err := http.ListenAndServe(":8080", nil); err != nil {
        fmt.Printf("启动服务器时出错: %v", err)
    }
}

在这个例子中,服务器处理 /greet 路径的 GET 请求,并尝试从查询参数中读取 name 值。如果未提供 name 参数,它将默认使用 "Guest" 作为名字。

结论

通过这些扩展案例,你已经学会了如何使用 Go 语言创建一个简单但功能丰富的 Web 服务器。你不仅能够处理静态文件请求,还能根据请求动态生成内容,这为进一步开发复杂的 Web 应用奠定了基础。随着你对 Go 语言和 Web 开发的深入学习,你将能够创建更加强大和灵活的 Web 应用。

1.3 变量和类型

在 Go 语言中,变量是存储数据的基本单位,而类型是变量能够存储数据的种类。理解变量和类型对于编写可靠和高效的 Go 程序至关重要。

1.3.1 基础知识讲解

变量声明

Go 语言提供了多种声明变量的方式:

  • 使用 var 关键字声明单个变量:

    var name string
    name = "Go Programmer"
    
  • 同时声明和初始化变量:

    var language = "Go"
    
  • 使用类型推断声明和初始化变量:

    framework := "Gin"
    
  • 声明多个变量:

    var x, y int = 1, 2
    var a, b = 123, "hello"
    c, d := true, 3.14
    

基本数据类型

Go 语言内置了一系列基本数据类型:

  • 整型(int, int8, int16, int32, int64
  • 浮点型(float32, float64
  • 布尔型(bool
  • 字符串(string
  • 复数类型(complex64, complex128

类型转换

Go 语言要求显式的类型转换,使用类型转换的语法格式为 Type(value)

var i int = 42
var f float64 = float64(i)
var u uint = uint(f)

1.3.2 重点案例:处理温度转换

温度转换是一个常见的问题,尤其是在处理国际化应用或科学计算时。我们已经探讨了如何将摄氏温度转换为华氏温度。现在,让我们扩展这个案例,包括更多的转换功能,例如华氏温度转换为摄氏温度,以及摄氏温度转换为开尔文温度。这些功能将被组织在一个更完整的程序中,提供一个实用的温度转换工具。

扩展功能

除了摄氏温度转华氏温度的转换外,我们还将实现以下功能:

  • 华氏温度转摄氏温度
  • 摄氏温度转开尔文温度
  • 开尔文温度转摄氏温度

实现代码

package main

import "fmt"

// CtoF converts Celsius to Fahrenheit
func CtoF(c float64) float64 {
    return (c * 9 / 5) + 32
}

// FtoC converts Fahrenheit to Celsius
func FtoC(f float64) float64 {
    return (f - 32) * 5 / 9
}

// CtoK converts Celsius to Kelvin
func CtoK(c float64) float64 {
    return c + 273.15
}

// KtoC converts Kelvin to Celsius
func KtoC(k float64) float64 {
    return k - 273.15
}

func main() {
    var celsius float64
    fmt.Print("Enter temperature in Celsius: ")
    fmt.Scanf("%f", &celsius)

    fahrenheit := CtoF(celsius)
    kelvin := CtoK(celsius)
    fmt.Printf("%g°C is %g°F\n", celsius, fahrenheit)
    fmt.Printf("%g°C is %gK\n", celsius, kelvin)

    fmt.Print("Enter temperature in Fahrenheit: ")
    fmt.Scanf("%f", &fahrenheit)
    celsius = FtoC(fahrenheit)
    fmt.Printf("%g°F is %g°C\n", fahrenheit, celsius)

    fmt.Print("Enter temperature in Kelvin: ")
    fmt.Scanf("%f", &kelvin)
    celsius = KtoC(kelvin)
    fmt.Printf("%gK is %g°C\n", kelvin, celsius)
}

使用说明

此程序提供了一个简单的命令行界面,允许用户输入摄氏温度、华氏温度或开尔文温度,并输出相应的温度转换结果。这个程序展示了如何使用 Go 语言进行基础的数学运算和标准输入输出操作,同时也展示了函数的定义和使用。

用户被提示输入一个温度值,程序将根据用户的输入计算并输出相应的转换结果。这种交互方式使得程序可以作为一个实用的命令行工具,用于快速进行常见的温度转换。

通过扩展原有的温度转换案例,我们不仅加深了对 Go 语言的理解,也提供了一个实用的工具,可以在实际工作中使用。这个案例展示了如何将基本的编程概念应用于解决实际问题,是学习编程语言的一个重要步骤。

1.3.3 拓展案例 1:货币转换

货币转换是金融应用和国际化服务中的常见需求。在这个扩展案例中,我们将开发一个简单的命令行工具,用于转换美元(USD)到欧元(EUR)和反向转换。这个工具将演示如何在 Go 程序中处理用户输入、进行计算和显示结果。

为了简化示例,我们将使用固定的汇率,但在实际应用中,你可能会从外部API获取实时汇率。

实现代码

package main

import (
    "fmt"
)

// 定义汇率常量
const (
    usdToEurRate = 0.85
    eurToUsdRate = 1 / usdToEurRate
)

// USDToEUR converts US Dollars to Euros
func USDToEUR(usd float64) float64 {
    return usd * usdToEurRate
}

// EURToUSD converts Euros to US Dollars
func EURToUSD(eur float64) float64 {
    return eur * eurToUsdRate
}

func main() {
    var amount float64
    var currency string

    fmt.Println("请输入金额和货币类型(USD 或 EUR):")
    _, err := fmt.Scanf("%f %s", &amount, &currency)
    if err != nil {
        fmt.Println("输入错误:", err)
        return
    }

    switch currency {
    case "USD":
        converted := USDToEUR(amount)
        fmt.Printf("$%.2f 美元等于 €%.2f 欧元\n", amount, converted)
    case "EUR":
        converted := EURToUSD(amount)
        fmt.Printf("€%.2f 欧元等于 $%.2f 美元\n", amount, converted)
    default:
        fmt.Println("不支持的货币类型。请输入 USD 或 EUR。")
    }
}

使用说明

此程序允许用户输入一个金额和货币类型(USD 或 EUR),然后计算并显示转换后的金额。用户需要按照 金额 货币类型 的格式输入,例如 100 USD85 EUR

通过处理用户输入,进行数学计算,并根据输入的货币类型选择正确的转换函数,这个程序展示了 Go 语言在实际应用中如何处理条件判断和基本的输入输出操作。

此案例不仅加深了对 Go 语言基础知识的理解,也提供了一个实用的工具,可以用于货币转换的快速计算。在实际开发中,你可以扩展此程序,比如通过调用外部API获取实时汇率,或增加更多的货币类型支持,从而使其成为一个更完整、更实用的货币转换工具。

1.3.4 拓展案例 2:字符串处理

字符串处理是编程中的常见任务,涉及到字符串的搜索、替换、分割、合并等操作。在这个扩展案例中,我们将开发一个更完整的命令行工具,用于执行多种字符串操作。这个工具将展示如何在 Go 程序中处理用户输入和执行字符串操作,提供一个实用的字符串处理工具。

实现代码

package main

import (
    "bufio"
    "fmt"
    "os"
    "strings"
)

func main() {
    reader := bufio.NewReader(os.Stdin)
    fmt.Println("请输入字符串:")
    input, _ := reader.ReadString('\n')
    input = strings.TrimSpace(input)

    fmt.Println("选择操作:")
    fmt.Println("1 - 大写转换")
    fmt.Println("2 - 小写转换")
    fmt.Println("3 - 反转字符串")
    fmt.Println("4 - 计算长度")
    var choice int
    fmt.Scan(&choice)

    switch choice {
    case 1:
        fmt.Println("大写:", strings.ToUpper(input))
    case 2:
        fmt.Println("小写:", strings.ToLower(input))
    case 3:
        fmt.Println("反转:", reverseString(input))
    case 4:
        fmt.Println("长度:", len(input))
    default:
        fmt.Println("未知操作")
    }
}

// reverseString 反转字符串
func reverseString(s string) string {
    runes := []rune(s)
    for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
        runes[i], runes[j] = runes[j], runes[i]
    }
    return string(runes)
}

使用说明

此程序提供了一个简单的菜单,允许用户输入一个字符串,然后选择要对该字符串执行的操作。用户可以选择将字符串转换为大写或小写,反转字符串,或计算其长度。

  • 当用户选择大写或小写转换时,程序将输入的字符串转换为相应的大小写形式。
  • 选择反转字符串时,程序将返回字符串的反向形式。
  • 选择计算长度时,程序将输出字符串的字符数。

这个程序通过提供基本的字符串处理功能,展示了 Go 语言在处理字符串方面的灵活性和强大功能。通过实现和使用 reverseString 函数,还演示了如何操作字符串中的字符来实现更复杂的逻辑。

此案例不仅加深了对 Go 语言字符串操作函数的理解,还提供了一个实用的工具,可用于执行常见的字符串处理任务。这个工具可以根据需要进一步扩展,比如添加更多的字符串操作功能,使其成为一个更全面的字符串处理工具。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/389938.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

为什么电路要设计得这么复杂?

首先提出这个问题就很不容易啊&#xff0c;我们看两个精彩回答。 From 骄建&#xff1a; 假设我们回到第一个实用放大电路诞生之前&#xff1a; 某天你开始做一个CS单管放大器&#xff0c;电阻负载&#xff0c;可是有一大堆问题&#xff0c;电阻做的不准&#xff0c;温度对器…

Kotlin基本语法 3 类

1.定义类 package classStudyclass Player {var name:String "jack"get() field.capitalize()set(value) {field value.trim()} }fun main() {val player Player()println(player.name)player.name " asdas "println(player.name)} 2.计算属性与防范…

jmeter遇到连接数据库的问题

jmeter连接mysql或者oracle简单&#xff0c;但是连接过inceptor吗&#xff1f; 上货 1、下载驱动inceptor 5.1.2.jar包 2、在添加驱动那里导入 3、在JBC request中的写法 PS:没什么可说的

【数据结构】10 广义表与多重链表

广义表 广义表不仅跟线性表一样可以表示简单是线性顺序关系&#xff0c;而且可以表达更复杂的非线性多元关系。 G L i s t ( a 1 , a 2 , . . . , a i − 1 , a i , a i 1 , . . . , a n ) GList (a_1, a_2,...,a_{i-1},a_i,a_{i1},...,a_n) GList(a1​,a2​,...,ai−1​,…

【机器学习笔记】7 KNN算法

距离度量 欧氏距离(Euclidean distance) 欧几里得度量&#xff08;Euclidean Metric&#xff09;&#xff08;也称欧氏距离&#xff09;是一个通常采用的距离定义&#xff0c;指在&#x1d45a;维空间中两个点之间的真实距离&#xff0c;或者向量的自然长度&#xff08;即该点…

分布式文件系统 SpringBoot+FastDFS+Vue.js【四】

分布式文件系统 SpringBootFastDFSVue.js【四】 八、文件的下载和删除功能8.1.FastDFSClient.java8.2.FileServerController.java8.3.Vue的fast.js8.4.fastdfsimg.vue8.5.效果 九、总结endl 八、文件的下载和删除功能 8.1.FastDFSClient.java Slf4j public class FastDFSClie…

websocket数据帧格式

客户端、服务端数据的交换&#xff0c;离不开数据帧格式的定义。因此&#xff0c;在实际讲解数据交换之前&#xff0c;我们先来看下WebSocket的数据帧格式。 WebSocket客户端、服务端通信的最小单位是帧&#xff08;frame&#xff09;&#xff0c;由1个或多个帧组成一条完整的消…

Atcoder ABC339 C - Perfect Bus

Perfect Bus&#xff08;完美的公交车&#xff09; 时间限制&#xff1a;2s 内存限制&#xff1a;1024MB 【原题地址】 所有图片源自Atcoder&#xff0c;题目译文源自脚本Atcoder Better! 点击此处跳转至原题 【问题描述】 【输入格式】 【输出格式】 【样例1】 【样例输…

排序算法---计数排序

原创不易&#xff0c;转载请注明出处。欢迎点赞收藏~ 计数排序&#xff08;Counting Sort&#xff09;是一种线性时间复杂度的排序算法&#xff0c;其核心思想是通过统计待排序元素的个数来确定元素的相对位置&#xff0c;从而实现排序。 具体的计数排序算法步骤如下&#xff…

Netty Review - 直接内存的应用及源码分析

文章目录 Pre概述应用访问效率&#xff1a; 堆内存 VS 直接内存申请效率&#xff1a; 堆内存 VS 直接内存数据存储结构&#xff1a; 堆内存 VS 直接内存结论 ByteBuffer.allocateDirect 源码分析unsafe.allocateMemory(size) ---> C方法 JVM参数 -XX:MaxDirectMemorySize直接…

视觉slam十四讲学习笔记(五)非线性优化

已经知道&#xff0c;方程中的位姿可以由变换矩阵来描述&#xff0c;然后用李代数进行优化。观测方程由相机成像模型给出&#xff0c;其中内参是随相机固定的&#xff0c;而外参则是相机的位姿。 目录 前言 一、状态估计问题 1 最大后验与最大似然 2 最小二乘的引出 二、非…

JavaScript中null和undefined的区别

JavaScript中null和undefined是两个特殊的值&#xff0c;经常在编程中遇到。虽然它们经常被混淆&#xff0c;但它们有着不同的含义和用法。本文将详细介绍JavaScript中null和undefined的区别&#xff0c;帮助开发者更好地理解和使用它们。 首先&#xff0c;让我们来了解一下nu…

css篇---移动端适配的方案有哪几种

移动端适配 移动端适配是指同一个页面可以在不同的移动端设备上都有合理的布局。主流实现的方案有 响应式布局通过rem或者vw,vh 等实现不同设备有相同的比例而实现适配 首先需要了解viewport 【视口】 视口代表了一个可看见的多边形区域&#xff08;通常来说是矩形&#xff0…

函数递归与迭代附n的阶乘+顺序打印一个整数的每一位数+求第n个斐波那契数

1. 什么是递归&#xff1f; 递归其实是一种解决问题的方法&#xff0c;在C语言中&#xff0c;递归就是函数自己调用自己。 下面是一个最简单的C语言递归代码&#xff1a; #include <stdio.h> int main() {printf("hehe\n");main();//main函数中⼜调⽤了main函数…

BBC英式口语~发音练习~笔记整理

参考资料 原视频地址&#xff1a; https://www.bilibili.com/video/BV1D7411n7bS/?spm_id_from333.1245.0.0&vd_source5986fc7c8e6d754f3ca44233573aeaff 笔记图片

2.11题目

#include <stdio.h> int main() { char a; while((a getchar()) ! -1) { if(a > A && a < Z) a32; putchar(ch); } return 0;} ———————————————— 版权声明&#xff1a;本文为博主原创文章…

阿里云/腾讯云幻兽帕鲁服务器据点最大帕鲁工作数量最多15个,改成20不生效?

例如&#xff0c;在阿里云的计算巢管理中&#xff0c;找到你的这台部署幻兽帕鲁的服务器实例&#xff0c;选择右上角的“修改游戏配置” 然后选择“基地内工作帕鲁的最大数量”改成20 有人说更改上面的数字&#xff0c;根本不起作用。原因可能如下&#xff1a; 参考资料&#…

css篇---分辨率物理像素和逻辑像素

物理分辨率和逻辑分辨率 物理分辨率是生产屏幕时就固定的&#xff0c;它是不可改变的 -----电脑像素 逻辑分辨率是由软件决定的 【电脑的设置中可以修改分辨率】----css像素 设备像素比 dpr同一方向上的物理像素/css像素 &#xff08;缩放比是1的情况&#xff09; 假设dpr4/…

网络安全最典型基础靶场-DVWA-本地搭建与初始化

写在前面&#xff1a; 之前也打过这个 DVWA 靶场&#xff0c;但是是在虚拟机环境下的一个小块分区靶场&#xff1b; 本篇博客主要介绍在本地搭建 DVWA 靶场以及靶场的初始化&#xff0c;后续会陆续更新通关教程。 由于我们是在本地搭建&#xff0c;则需要基于你已经装好 phpstu…

cefsharp121(cef121.3.7Chromium121.0.6167.160)升级测试及其他H264版本

一、版本说明 1.1 本此版本 此版本CEF 121.3.7+g82c7c57+chromium-121.0.6167.160 / Chromium 121.0.6167.160 1.2 其他支持H264版本 支持H264推荐版本:V100,V109,V111,V119版本,其他V114,V115,V108,V107 支持win7/win8/win8.1最后版本v109.x 支持NET4.5.2最后版本v114.x …