通过示例学习 Go 语言 2023(二十九)

在 HTTP 响应中返回 401(未授权)状态码的 Go(Golang)实现。

来源:golangbyexample.com/401-http-status-response-go/

目录

  • 概述

  • 程序

概述

net/http包提供状态码常量,可用于返回不同的状态码 - golang.org/src/net/http/status.go

同样可以用于返回 401(未授权)HTTP 状态码。HTTP 401 状态码由以下常量定义。

http.StatusUnauthorized

在本文中,我们还将看到如何在返回 401(未授权)状态码的同时返回 JSON 主体。

程序

以下是相应的程序。

package main

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

func main() {
	handler := http.HandlerFunc(handleRequest)
	http.Handle("/example", handler)
	http.ListenAndServe(":8080", nil)
}

func handleRequest(w http.ResponseWriter, r *http.Request) {
	w.WriteHeader(http.StatusUnauthorized)
	w.Header().Set("Content-Type", "application/json")
	resp := make(map[string]string)
	resp["message"] = "Unauthorized"
	jsonResp, err := json.Marshal(resp)
	if err != nil {
		log.Fatalf("Error happened in JSON marshal. Err: %s", err)
	}
	w.Write(jsonResp)
	return
}

在这里,我们使用WriteHeader函数来指定 401 HTTP 状态码,并使用Write函数来返回响应主体。上述代码将返回以下 JSON 请求主体作为响应。

{"message":"Unauthorized"}

运行上述程序。它将在本地机器的 8080 端口启动一个服务器。现在对服务器进行以下 curl 调用。

curl -v -X POST http://localhost:8080/example

以下将是输出。

* Connected to localhost (::1) port 8080 (#0)
> POST /example HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.54.0
> Accept: */*
> 
< HTTP/1.1 401 Unauthorized
< Date: Sat, 10 Jul 2021 08:19:52 GMT
< Content-Length: 26
< Content-Type: text/plain; charset=utf-8
< 
* Connection #0 to host localhost left intact
{"message":"Unauthorized"}

如你所见,输出将正确返回401状态码及其主体。

你也可以直接将 401 传递给 WriteHeader 函数以发送 401 响应。

w.WriteHeader(401)

这也可以正常工作。试试看。

同时,查看我们的 Golang 高级教程系列 - Golang 高级教程

在 Go (Golang)中返回 403(禁止)状态码的 HTTP 响应

来源:golangbyexample.com/403-http-status-response-golang/

目录

  • 概述

  • 程序

概述

net/http包提供了状态码常量,可以用于返回不同的状态码-

golang.org/src/net/http/status.go

同样的方式也可以用来返回 403(禁止)HTTP 状态码。HTTP 403 状态码由以下常量定义。

http.StatusForbidden

在本文中,我们还将看到如何返回带有 403(禁止)状态码的 JSON 主体。

程序

以下是相应的程序

package main

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

func main() {
	handler := http.HandlerFunc(handleRequest)
	http.Handle("/example", handler)
	http.ListenAndServe(":8080", nil)
}

func handleRequest(w http.ResponseWriter, r *http.Request) {
	w.WriteHeader(http.StatusForbidden)
	w.Header().Set("Content-Type", "application/json")
	resp := make(map[string]string)
	resp["message"] = "Forbidden"
	jsonResp, err := json.Marshal(resp)
	if err != nil {
		log.Fatalf("Error happened in JSON marshal. Err: %s", err)
	}
	w.Write(jsonResp)
	return
}

在这里,我们使用WriteHeader函数来指定 403 HTTP 状态码,并使用Write函数返回响应体。上述代码将以下 JSON 请求体作为响应返回。

{"message":"Forbidden"}

运行上述程序。它将在你本地机器的 8080 端口启动一个服务器。现在进行以下 curl 调用到服务器。

curl -v -X POST http://localhost:8080/example

下面将是输出。

* Connected to localhost (::1) port 8080 (#0)
> POST /example HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.54.0
> Accept: */*
> 
< HTTP/1.1 403 Forbidden
< Date: Sat, 10 Jul 2021 08:16:22 GMT
< Content-Length: 23
< Content-Type: text/plain; charset=utf-8
< 
* Connection #0 to host localhost left intact
{"message":"Forbidden"}

正如你从输出中看到的,它将正确返回 403 状态码及其主体。

你也可以直接将 403 传递给 WriteHeader 函数以发送 403 响应。

w.WriteHeader(403)

这同样工作正常。试试看。

另外,查看我们的 Golang 进阶教程系列 - Golang 进阶教程

在 Go(Golang)中返回 404(资源未找到)HTTP 响应状态码。

来源:golangbyexample.com/404-http-status-code-golang/

目录

  • 概述

  • 程序

概述

golang 的 HTTP 包提供了可以用于返回不同状态码的状态码常量 - golang.org/src/net/http/status.go

同样也可以用于返回 404(资源未找到)HTTP 状态码。HTTP 404 状态码由下面的常量定义。

http.StatusNotFound

在本文中,我们还将看到如何在返回 404(资源未找到)HTTP 状态码时返回 JSON 正文。

程序

下面是相同的程序。

package main

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

func main() {
	handler := http.HandlerFunc(handleRequest)
	http.Handle("/example", handler)
	http.ListenAndServe(":8080", nil)
}

func handleRequest(w http.ResponseWriter, r *http.Request) {
	w.WriteHeader(http.StatusNotFound)
	w.Header().Set("Content-Type", "application/json")
	resp := make(map[string]string)
	resp["message"] = "Resource Not Found"
	jsonResp, err := json.Marshal(resp)
	if err != nil {
		log.Fatalf("Error happened in JSON marshal. Err: %s", err)
	}
	w.Write(jsonResp)
	return
}

在这里,我们使用WriteHeader函数指定 404 HTTP 状态码,并使用Write函数返回响应正文。上述代码将下面的 JSON 请求正文返回作为响应。

{"message":"Resource Not Found"}

运行上述程序。它将在你的本地机器上启动一个 8080 端口的服务器。现在对服务器进行如下 curl 调用。

curl -v -X POST http://localhost:8080/example

下面将是输出。

* Connected to localhost (::1) port 8080 (#0)
> POST /example HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.54.0
> Accept: */*
> 
< HTTP/1.1 404 Not Found
< Date: Sat, 10 Jul 2021 06:18:12 GMT
< Content-Length: 32
< Content-Type: text/plain; charset=utf-8
< 
* Connection #0 to host localhost left intact
{"message":"Resource Not Found"}

从输出中可以看出,它正确地返回了404状态码及其正文。

你也可以直接将 404 传递给WriteHeader函数来发送 404 响应。

w.WriteHeader(404)

这也能正常工作。试试看。

golang 的net/http包也提供了一个**“NotFound”**处理程序,可以用于每次返回特定 API 的 404。

golang.org/pkg/net/http/#NotFound

此处理程序函数返回 404 状态及下面的响应正文。

404 page not found

下面是相同的简单程序。

package main

import (
	"net/http"
)

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

在上述程序中,我们简单地为localhost:8080/example API 指定了 NotFound 处理程序,如下所示。

http.HandleFunc("/example", http.NotFound)

运行上述程序。它将在你的本地机器上启动一个 8080 端口的服务器。现在对服务器进行如下 curl 调用。

curl -v -X POST http://localhost:8080/example
* Connected to localhost (::1) port 8080 (#0)
> POST /example HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.54.0
> Accept: */*
> 
< HTTP/1.1 404 Not Found
< Content-Type: text/plain; charset=utf-8
< X-Content-Type-Options: nosniff
< Date: Sat, 10 Jul 2021 06:23:41 GMT
< Content-Length: 19
< 
404 page not found
* Connection #0 to host localhost left intact

此外,请查看我们的 Golang 高级教程系列 - Golang 高级教程

在 Go(Golang)中返回 500 状态码或内部服务器错误的 HTTP 响应

来源:golangbyexample.com/500-status-http-response-golang/

目录

  • 概述

  • 程序

概述

net/http包的 golang 提供了状态码常量,可用于返回不同的状态码 - golang.org/src/net/http/status.go

同样也可以用来返回 500(StatusInternalServerError)HTTP 状态码。HTTP 500 状态码由以下常量定义。

http.StatusInternalServerError

在本文中,我们还将看到如何返回带有 500(StatusInternalServerError)状态码的 JSON 体。

程序

以下是相同的程序。

package main

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

func main() {
	handler := http.HandlerFunc(handleRequest)
	http.Handle("/example", handler)
	http.ListenAndServe(":8080", nil)
}

func handleRequest(w http.ResponseWriter, r *http.Request) {
	w.WriteHeader(http.StatusInternalServerError)
	w.Header().Set("Content-Type", "application/json")
	resp := make(map[string]string)
	resp["message"] = "Some Error Occurred"
	jsonResp, err := json.Marshal(resp)
	if err != nil {
		log.Fatalf("Error happened in JSON marshal. Err: %s", err)
	}
	w.Write(jsonResp)
	return
}

在这里,我们使用WriteHeader函数指定 500 的 http 状态码,并使用Write函数返回响应体。上述代码在响应中返回以下 JSON 请求体。

{"message":"Some Error Occurred"}

运行上述程序。这将在你的本地机器上启动一个 8080 端口的服务器。现在对服务器进行以下 curl 调用。

curl -v -X POST http://localhost:8080/example

以下将是输出

* Connected to localhost (::1) port 8080 (#0)
> POST /example HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.54.0
> Accept: */*
> 
< HTTP/1.1 500 Internal Server Error
< Date: Sat, 10 Jul 2021 10:49:52 GMT
< Content-Length: 33
< Content-Type: text/plain; charset=utf-8
< 
* Connection #0 to host localhost left intact
{"message":"Some Error Occurred"}

从输出中可以看到,它将正确返回 500 状态码以及响应体。

你也可以直接将 500 传递给 WriteHeader 函数以发送 500 响应。

w.WriteHeader(500)

这也能正常工作。试试看。

另外,查看我们的 Golang 进阶教程系列 - Golang 进阶教程

在 Go (Golang) 中从函数返回一个函数

来源:golangbyexample.com/return-func-from-func-go/

在 Golang 中,函数是一级变量,这意味着

  • 它们可以被赋值给一个变量

  • 作为函数参数传递

  • 从函数返回

在从另一个函数返回一个函数时,必须在返回列表中指定函数的确切签名。如下例所示

  • getAreaFunc 函数的返回类型是 func(int, int) int
func getAreaFunc() func(int, int)
  • getAreaFunc 函数因此可以返回类型为 func(int, int) int 的函数

代码:

package main

import "fmt"

func main() {
    areaF := getAreaFunc()
    res := areaF(2, 4)
    fmt.Println(res)
}

func getAreaFunc() func(int, int) int {
    return func(x, y int) int {
        return x * y
    }
}

输出:

8

在 Go(Golang)中以 HTTP 响应返回图像或文件。

来源:golangbyexample.com/image-http-response-golang/

目录

概述

  • 示例

概述

ResponseWriter 接口的 Write 方法可以用于在 HTTP 响应体中发送 imagefile。当我们将文件或图像作为 HTTP 响应的一部分发送时,Content-Type 响应头为

application/octet-stream

在 Go 中,响应由 ResponseWriter 接口表示。这里是接口的链接 –

https://golang.org/pkg/net/http/#ResponseWriter

ResponseWriter 接口由 HTTP 处理程序用于构造 HTTP 响应。它提供了三个函数来设置响应参数。

  • Header – 用于写入响应头。

  • Write([]byte) – 用于写入响应体。

  • WriteHeader(statusCode int) – 用于写入 HTTP 状态码。

Write 函数可用于设置响应体。它接受一个字节切片作为输入。因此,我们需要先将文件或图像读取到字节切片中,然后再将其作为参数传递给 Write 函数。为此,我们将使用 ioutil 包提供的 ReadFile 函数。此外,还有一个 Header 函数。此函数可用于使用 Content-Type 头设置响应体的内容类型。

w.Header().Set("Content-Type", "application/octet-stream")

此外,请注意 WriteHeader 函数可用于设置响应的 HTTP 状态码。

示例

让我们看看如何将文件或图像作为 HTTP 响应的一部分发送的示例。下面是相应的程序。

package main

import (
	"io/ioutil"
	"net/http"
)

func main() {
	handler := http.HandlerFunc(handleRequest)
	http.Handle("/photo", handler)
	http.ListenAndServe(":8080", nil)
}

func handleRequest(w http.ResponseWriter, r *http.Request) {
	fileBytes, err := ioutil.ReadFile("test.png")
	if err != nil {
		panic(err)
	}
	w.WriteHeader(http.StatusOK)
	w.Header().Set("Content-Type", "application/octet-stream")
	w.Write(fileBytes)
	return
}

这就是我们如何在 Go 中将文件或图像读取到变量中的。

fileBytes, err := ioutil.ReadFile("test.png")

然后我们将这个变量传递给 Write 函数。

w.Write(fileBytes)

请注意,在上面的程序中,我们发送的是本地机器上存在的 test.png。您可以将其替换为您机器上存在的任何其他文件,可以是 png 或其他文件。

此外,我们正在使用 WriteHeader 函数来指定 200 HTTP 状态码。我们还设置了正确的头部。

w.Header().Set("Content-Type", "application/octet-stream")

运行上面的程序。它将在您本地机器的 8080 端口启动一个服务器。现在向服务器发出下面的 curl 调用。请注意在 curl 调用中,我们还将输出保存到本地文件。

curl -v -X POST http://localhost:8080/example > temp.png

输出将类似于下面的内容。

* Connected to localhost (::1) port 8080 (#0)
> POST /example HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.54.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Date: Sat, 10 Jul 2021 19:32:47 GMT
< Content-Type: image/png
< Transfer-Encoding: chunked
< 
{ [5846 bytes data]
100  5833    0  5833    0     0   957k      0 --:--:-- --:--:-- --:--:-- 1139k

现在检查您从中发出 curl 调用的当前目录。在该目录下会有一个名为 test.png 的文件,这就是服务器发送的相同文件。

此外,请查看我们的 Golang 高级教程系列 - Golang 高级教程

在 Go (Golang) 中返回退出状态码

来源:golangbyexample.com/return-exit-status-code-go/

目录

  • 概述**

  • 代码

概述

golang 的 ‘os’ 包提供了一个 Exit 函数,可以用来以状态码退出当前程序。

  • 状态码零表示成功

  • 非零状态码表示错误。

一旦调用此函数,程序会立即退出。即使是延迟函数也不会被调用。

还需注意状态码应在范围 [0, 125] 内

func Exit(code int)

让我们来看一个工作代码

代码

package main

import (
    "fmt"
    "os"
)

func main() {
    success := true
    if success {
        fmt.Println("Success")
        os.Exit(0)
    } else {
        fmt.Println("Failure")
        os.Exit(1)
    }
}

输出

尝试将成功设置为 false,以查看不同的输出

Success
$ echo $?
0

在 Go(Golang)中返回 JSON 体作为 HTTP 响应

来源:golangbyexample.com/json-response-body-http-go/

目录

  • 概述**

  • 示例

概述

net/http包中 ResponseWriter 接口的Write方法可用于在 HTTP 响应中设置 JSON 体

在 GO 中,响应由ResponseWriter接口表示。这里是接口的链接 –

golang.org/pkg/net/http/#ResponseWriter

ResponseWriter 接口由 HTTP 处理程序用于构建 HTTP 响应。它提供三个函数来设置响应参数

  • 头部 – 用于写入响应头

  • Write([]byte) – 用于写入响应体

  • WriteHeader(statusCode int) – 用于写入 HTTP 状态码

Write函数可以用于设置响应体。它接受一个字节切片作为输入。此外,还有一个Header函数。该函数可用于通过 Content-Type 头设置响应体的内容类型。例如,在 JSON 响应体的情况下,我们需要将 Content-Type 头设置为**“application/json”。**

w.Header().Set("Content-Type", "application/json")

另外,请注意WriteHeader函数可以用于设置响应的 HTTP 状态码

示例

让我们来看一个发送 HTTP 状态码和 JSON 响应体的示例

以下是相同的程序

package main

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

func main() {
	handler := http.HandlerFunc(handleRequest)
	http.Handle("/example", handler)
	http.ListenAndServe(":8080", nil)
}

func handleRequest(w http.ResponseWriter, r *http.Request) {
	w.WriteHeader(http.StatusCreated)
	w.Header().Set("Content-Type", "application/json")
	resp := make(map[string]string)
	resp["message"] = "Status Created"
	jsonResp, err := json.Marshal(resp)
	if err != nil {
		log.Fatalf("Error happened in JSON marshal. Err: %s", err)
	}
	w.Write(jsonResp)
	return
}

在上述程序中,这就是我们如何创建 JSON 响应。我们使用json.Marshal函数将map[string]string转换为 JSON 字节。

resp := make(map[string]string)
resp["message"] = "Status Created"
jsonResp, err := json.Marshal(resp)
if err != nil {
	log.Fatalf("Error happened in JSON marshal. Err: %s", err)
}
w.Write(jsonResp)

然后它使用Write函数返回 JSON 响应体。上述代码返回以下 JSON 响应体作为响应

{"message":"Status Created"}

此外,我们使用WriteHeader函数来指定 201 HTTP 状态码。

运行上述程序。它将在本地机器的 8080 端口启动一个服务器。现在请对服务器进行以下 curl 调用

curl -v -X POST http://localhost:8080/example

以下将是输出

* Connected to localhost (::1) port 8080 (#0)
> POST /example HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.54.0
> Accept: */*
> 
< HTTP/1.1 201 Created
< Date: Sat, 10 Jul 2021 10:40:33 GMT
< Content-Length: 28
< Content-Type: text/plain; charset=utf-8
< 
* Connection #0 to host localhost left intact
{"message":"Status Created"}

从输出中可以看到,它将正确返回201状态码以及 JSON 体。

另外,请查看我们的 Golang 高级教程系列 - Golang 高级教程

在 Go(Golang)中返回纯文本体的 HTTP 响应。

来源:golangbyexample.com/plain-text-response-body-golang/

目录

  • 概述

  • 示例

概述

Write方法的 ResponseWriter 接口在net/http包中可用于在 HTTP 响应中设置text/plain体。

在 GO 中,响应由ResponseWriter接口表示。接口的链接在这里 – golang.org/pkg/net/http/#ResponseWriter

ResponseWriter 接口由 HTTP 处理程序用于构造 HTTP 响应。它提供三个函数来设置响应参数。

  • Header – 用于写入响应头。

  • Write([]byte) – 用于写入响应体。

  • WriteHeader(statusCode int) – 用于写入 HTTP 状态码。

Write函数可用于设置响应体。它接受一个字节切片作为输入。此外,还有一个Header函数。此函数可用于通过 Content-Type 头设置响应体的内容类型。例如,对于 text/plain 响应体,我们需要将 Content-Type 头设置为**“text/plain”。**

w.Header().Set("Content-Type", "text/plain")

此外,请注意WriteHeader函数可用于设置响应的 HTTP 状态码。

示例

让我们看看发送 HTTP 状态码和text/plain响应体的示例。

下面是相应的程序。

package main

import (
	"net/http"
)

func main() {
	handler := http.HandlerFunc(handleRequest)
	http.Handle("/example", handler)
	http.ListenAndServe(":8080", nil)
}

func handleRequest(w http.ResponseWriter, r *http.Request) {
	w.WriteHeader(http.StatusOK)
	w.Header().Set("Content-Type", "application/text")
	w.Write([]byte("Success"))
	return
}

我们使用Write函数返回 text/plain 响应体。上述代码返回以下text/plain体作为响应。

Success

此外,我们正在使用WriteHeader函数来指定200的 HTTP 状态码。我们还设置了正确的头信息。

运行上述程序。它将在本地机器的 8080 端口启动一个服务器。现在对服务器进行以下 curl 调用。

curl -v -X POST http://localhost:8080/example

下面将是输出。

* Connected to localhost (::1) port 8080 (#0)
> POST /example HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.54.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Date: Sat, 10 Jul 2021 19:01:56 GMT
< Content-Length: 7
< Content-Type: text/plain; charset=utf-8
< 
* Connection #0 to host localhost left intact
Success

从输出中可以看到,它将正确返回200状态码以及text/plain体。此外,Content-Type响应头被设置为text/plain

此外,请查看我们的 Golang 进阶教程系列 - Golang 进阶教程

当恐慌在 Go(Golang)中被恢复时,函数的返回值

来源:golangbyexample.com/return-value-function-panic-recover-go/

目录

  • 概述

  • 程序

概述

当恐慌被恢复时,恐慌函数的返回值将是该函数返回类型的默认值。

程序

让我们来看一个程序示例

package main
import (
    "fmt"
)
func main() {
    a := []int{5, 6}
    val, err := checkAndGet(a, 2)
    fmt.Printf("Val: %d\n", val)
    fmt.Println("Error: ", err)
}
func checkAndGet(a []int, index int) (int, error) {
    defer handleOutOfBounds()
    if index > (len(a) - 1) {
        panic("Out of bound access for slice")
    }
    return a[index], nil
}
func handleOutOfBounds() {
    if r := recover(); r != nil {
        fmt.Println("Recovering from panic:", r)
    }
}

输出

Recovering from panic: Out of bound access for slice
Val: 0
Error: 

在上面的程序中,我们有一个checkAndGet函数,它获取 int 切片中特定索引的值。如果传递给此函数的索引大于(切片长度-1),则会引发恐慌。同时还有一个handleOutOfBounds函数用于从恐慌中恢复。因此,我们将索引 2 传递给checkAndGet函数,它引发了恐慌,并在handleOutOfBounds函数中得以恢复。这就是我们首先得到这个输出的原因。

Recovering from panic: Out of bound access for slice

请注意在主函数中,我们以这样的方式重新获取checkAndGet的返回值。

val, err := checkAndGet(a, 2)

checkAndGet有两个返回值

  • int

  • error

由于checkAndGet会引发恐慌,而该恐慌在 handleOutOfBounds 函数中被恢复,因此checkAndGet的返回值将是其类型的默认值。

因此

fmt.Printf("Val: %d\n", val)

输出

Val: 0

因为零是int类型的默认值。

而且

fmt.Println("Error: ", err)

输出

Error: 

因为 nil 是error类型的默认值。

如果你不想返回类型的默认零值,那么可以使用命名返回值。我们来看一个程序示例。

package main
import (
    "fmt"
)
func main() {
    a := []int{5, 6}
    val, err := checkAndGet(a, 2)
    fmt.Printf("Val: %d\n", val)
    fmt.Println("Error: ", err)
}
func checkAndGet(a []int, index int) (value int, err error) {
    value = 10
    defer handleOutOfBounds()
    if index > (len(a) - 1) {
        panic("Out of bound access for slice")
    }
    value = a[index]
    return value, nil
}
func handleOutOfBounds() {
    if r := recover(); r != nil {
        fmt.Println("Recovering from panic:", r)
    }
}

输出

Recovering from panic: Out of bound access for slice
Val: 10
Error: 

这个程序与前面的程序相同,唯一的区别是我们在checkAndGet函数中使用了命名返回值。

func checkAndGet(a []int, index int) (value int, err error)

我们在checkAndGet函数中将命名返回值设置为 10

value = 10

这就是为什么我们在这个程序中得到以下输出,因为引发了恐慌并得以恢复

Recovering from panic: Out of bound access for slice
Val: 10
Error: 

还要注意,如果程序中没有引发恐慌,那么它将输出正确的索引值。

在 Go (Golang) 中从函数返回多个值

来源:golangbyexample.com/go-return-multiples-values-function/

目录

  • 概述

  • 函数的签名

  • 返回值

    • 代码:
  • 命名返回值

    • 代码:

概述

函数是一组执行特定任务的语句。

函数的签名

func func_name(input_parameters) return_values{
  //body
}

在 Golang 中,一个函数可以返回多个值。下面是一个函数的示例。

  • 名称为 “f”

  • 接受两个整型参数

  • 返回一个整型的单个值

func f(a int, b int) int {
  return a + b 
}

返回值

  • 如上所述,一个函数可以有一个或多个返回值。假设有一个函数 sum_avg 返回两个值:总和和平均值。注意,当返回多个值时,返回值类型必须用括号括起来。多个返回值的示例。
func sum_avg(a, b int) (int, int)
  • 根据约定,错误作为函数的最后一个参数返回。示例
func sum(a, b int) (int, error)
  • 在调用函数中收集多个返回值。在下面的示例中
result, err := sum(2, 3) 

代码:

package main

import "fmt"

func main() {
    sum, avg := sum_avg(4, 2)
    fmt.Println(sum)
    fmt.Println(avg)
}

func sum_avg(a, b int) (int, int) {
    sum := a + b
    avg := (a + b) / 2
    return sum, avg
}

输出

6
3

命名返回值

Go 函数可以具有命名返回值。使用命名返回值时,返回值在函数中不需要初始化。命名变量在签名中指定。没有命名值时,只指定返回类型。也可以为某些返回值命名。对于其他返回值,只能指定类型。

  • 见下面的示例:result 是命名返回值。
func sum(a, b int) (result int)
  • 多个命名返回值
func sum_avg(a, b int) (sum int, avg int)
  • 使用命名返回值时,相同类型的连续值只需指定一次类型。
func sum_avg(a, b int) (sum, avg int)
  • 命名返回值被初始化为该类型的零值。因此我们不需要在函数中重新初始化它。在下面的示例中,sumavg 没有使用 := 符号再次初始化。

代码:

package main

import "fmt"

func main() {
    sum, avg := sum_avg(4, 2)
    fmt.Println(sum)
    fmt.Println(avg)
}

func sum_avg(a, b int) (sum, avg int) {
    sum = a + b
    avg = (a + b) / 2
    return
} 

输出

6
3
```*


<!--yml

类别: 未分类

日期: 2024-10-13 06:42:59

-->

# 在 Go (Golang)中反转链表

> 来源:[`golangbyexample.com/reverse-linked-list-golang/`](https://golangbyexample.com/reverse-linked-list-golang/)

目录

+   概述

+   程序

## **概述**

目标是反转给定的链表。

示例

```go
Input:  3->2->1
Output: 1->2->3

程序

以下是相应的程序

package main

import "fmt"

func main() {
	first := initList()
	first.AddFront(1)
	first.AddFront(2)
	first.AddFront(3)
	first.AddFront(4)

	first.Head.Traverse()
	first.Reverse()
        fmt.Println("")
	first.Head.Traverse()

}

func initList() *SingleList {
	return &SingleList{}
}

type ListNode struct {
	Val  int
	Next *ListNode
}

func (l *ListNode) Traverse() {
	for l != nil {
		fmt.Println(l.Val)
		l = l.Next
	}
}

type SingleList struct {
	Len  int
	Head *ListNode
}

func (s *SingleList) Reverse() {

	curr := s.Head
	var prev *ListNode
	var next *ListNode

	for curr != nil {
		next = curr.Next
		curr.Next = prev
		prev = curr
		curr = next
	}
	s.Head = prev
}
func (s *SingleList) AddFront(num int) {
	ele := &ListNode{
		Val: num,
	}
	if s.Head == nil {
		s.Head = ele
	} else {
		ele.Next = s.Head
		s.Head = ele
	}
	s.Len++
}

输出

4
3
2
1

1
2
3
4

注意: 请查看我们的 Golang 高级教程。本系列的教程内容详尽,力求涵盖所有概念和示例。此教程适合希望获得专业知识和扎实理解的 Golang 学习者 – Golang 高级教程

如果你有兴趣了解所有设计模式如何在 Golang 中实现。如果是的话,那么这篇文章就是为你准备的 – 所有设计模式 Golang

在 Go 语言中反转一个数字或整数

来源:golangbyexample.com/reverse-number-golang/

目录

  • 概述

  • 程序

概述

目标是反转一个整数。整数可以是负数。以下是一些示例

Input: 123
Output: 321

Input: 140
Output: 41

Input: -123
Output: -321

Input: 0
Output: 0

这里是策略

  • 首先,将输入数字变为正数

  • 使用下面的逻辑遍历数字,每次获取最后一位数字。使用最后一位数字来创建reversedDigit

for x > 0 {
	lastDigit := x % 10
	reversedDigit = reversedDigit*10 + lastDigit

	x = x / 10
}

这里是完整的程序。

程序

package main

import (
	"fmt"
	"math"
)

func main() {
	reversedInteger := reverse(123)
	fmt.Println(reversedInteger)

	reversedInteger = reverse(140)
	fmt.Println(reversedInteger)

	reversedInteger = reverse(-123)
	fmt.Println(reversedInteger)

	reversedInteger = reverse(0)
	fmt.Println(reversedInteger)
}

func reverse(x int) int {
	sign := "positive"
	if x >= 0 {
		sign = "positive"
	} else {
		sign = "negative"
	}

	x = int(math.Abs(float64(x)))

	var reversedDigit int

	for x > 0 {
		lastDigit := x % 10
		reversedDigit = reversedDigit*10 + lastDigit

		x = x / 10
	}

	if sign == "negative" {
		reversedDigit = reversedDigit * -1
	}
	return reversedDigit
}

输出

321
41
-321
0

在 Go (Golang)中反转字符串

来源:golangbyexample.com/reverse-a-string-in-golang/

在 Golang 中,字符串是一个字节序列。字符串字面量实际上表示的是一个 UTF-8 字节序列。在 UTF-8 中,ASCII 字符是单字节的,对应于前 128 个 Unicode 字符。所有其他字符的字节数在 1 到 4 字节之间。因此,无法在字符串中索引一个字符。在 GO 中,rune数据类型表示一个 Unicode 点。一旦字符串被转换为rune数组,就可以在该数组中索引字符。你可以在这里了解更多关于rune的内容 – golangbyexample.com/understanding-rune-in-golang

因此,在下面的程序中为了反转一个字符串,我们首先将字符串转换为rune数组,以便可以索引该数组以获取单个字符。一旦我们获得了单个字符,就可以从末尾开始不断添加到一个新字符串中。

package main

import "fmt"

func main() {
    sample := "ab£d"
    r := []rune(sample)
    var res []rune
    for i := len(r) - 1; i >= 0; i-- {
        res = append(res, r[i])
    }
    fmt.Printf("Result: %s\n", string(res))
}

输出:

Result: d£ba

在 Go 中反转双向链表 (Golang)

来源:golangbyexample.com/reverse-doubly-linked-list-golang/

目录

  • 概述

  • 程序

概述

双向链表可以通过以下两种方法反转:

  • 通过交换节点的前后指针。

  • 通过使用栈

在本教程中,我们将介绍第一种方法,即通过交换前后指针。

假设我们有以下双向链表

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

反转后,双向链表将如下所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

程序

在这种方法中,我们需要注意以下几点:

  • 交换双向链表的头和尾

  • 交换所有节点的前后指针

package main
import "fmt"
type node struct {
    data string
    prev *node
    next *node
}
type doublyLinkedList struct {
    len  int
    tail *node
    head *node
}
func initDoublyList() *doublyLinkedList {
    return &doublyLinkedList{}
}
func (d *doublyLinkedList) AddFrontNodeDLL(data string) {
    newNode := &node{
        data: data,
    }
    if d.head == nil {
        d.head = newNode
        d.tail = newNode
    } else {
        newNode.next = d.head
        d.head.prev = newNode
        d.head = newNode
    }
    d.len++
}
func (d *doublyLinkedList) AddEndNodeDLL(data string) {
    newNode := &node{
        data: data,
    }
    if d.head == nil {
        d.head = newNode
        d.tail = newNode
    } else {
        currentNode := d.head
        for currentNode.next != nil {
            currentNode = currentNode.next
        }
        newNode.prev = currentNode
        currentNode.next = newNode
        d.tail = newNode
    }
    d.len++
}
func (d *doublyLinkedList) TraverseForward() error {
    if d.head == nil {
        return fmt.Errorf("TraverseError: List is empty")
    }
    temp := d.head
    for temp != nil {
        fmt.Printf("value = %v, prev = %v, next = %v\n", temp.data, temp.prev, temp.next)
        temp = temp.next
    }
    fmt.Println()
    return nil
}
func (d *doublyLinkedList) Size() int {
    return d.len
}
func (d *doublyLinkedList) ReverseDLL() {
    currentNode := d.head
    var nextInList *node
    d.head, d.tail = d.tail, d.head
    for currentNode != nil {
        nextInList = currentNode.next
        currentNode.next, currentNode.prev = currentNode.prev, currentNode.next
        currentNode = nextInList
    }
}
func main() {
    doublyList := initDoublyList()
    fmt.Printf("Add Front Node: C\n")
    doublyList.AddFrontNodeDLL("C")
    fmt.Printf("Add Front Node: B\n")
    doublyList.AddFrontNodeDLL("B")
    fmt.Printf("Add Front Node: A\n")
    doublyList.AddFrontNodeDLL("A")
    fmt.Printf("Add End Node: D\n")
    doublyList.AddEndNodeDLL("D")
    fmt.Printf("Add End Node: E\n")
    doublyList.AddEndNodeDLL("E")
    fmt.Printf("Size of doubly linked ist: %d\n", doublyList.Size())
    err := doublyList.TraverseForward()
    if err != nil {
        fmt.Println(err.Error())
    }
    fmt.Println("Reversing Doubly Linked List")
    doublyList.ReverseDLL()
    fmt.Printf("Size of doubly linked ist: %d\n", doublyList.Size())
    err = doublyList.TraverseForward()
    if err != nil {
        fmt.Println(err.Error())
    }
}

输出

Add Front Node: C
Add Front Node: B
Add Front Node: A
Add End Node: D
Add End Node: E
Size of doubly linked ist: 5
value = A, prev = <nil>, next = &{B 0xc000070060 0xc000070020}
value = B, prev = &{A <nil>0xc000070040}, next = &{C 0xc000070040 0xc000070080}
value = C, prev = &{B 0xc000070060 0xc000070020}, next = &{D 0xc000070020 0xc0000700a0}
value = D, prev = &{C 0xc000070040 0xc000070080}, next = &{E 0xc000070080 <nil>}
value = E, prev = &{D 0xc000070020 0xc0000700a0}, next = <nil>Reversing Doubly Linked List
Size of doubly linked ist: 5
value = E, prev = <nil>, next = &{D 0xc0000700a0 0xc000070020}
value = D, prev = &{E <nil>0xc000070080}, next = &{C 0xc000070080 0xc000070040}
value = C, prev = &{D 0xc0000700a0 0xc000070020}, next = &{B 0xc000070020 0xc000070060}
value = B, prev = &{C 0xc000070080 0xc000070040}, next = &{A 0xc000070040 <nil>}
value = A, prev = &{B 0xc000070020 0xc000070060}, next =</nil></nil></nil></nil></nil></nil></nil> 

此外,请查看我们的 Golang 高级教程系列 – Golang 高级教程

在 Go 语言中,针对给定链表按 k 组反转节点

来源:golangbyexample.com/reverse-nodes-k-group-linked-list-golang/

目录

  • 概述

  • 程序

概述

给定一个链表和一个数字 k,按 k 组反转链表中的节点。

例如

Input: 1->2->3->4->5->6->7
k: 3
Output: 3->2->1->6->5->4->7

如果链表最后一组的长度小于 k,则保留最后一组不变

程序

package main

import "fmt"

func main() {
	first := initList()
	first.AddFront(4)
	first.AddFront(3)
	first.AddFront(2)
	first.AddFront(1)

	first.Head.Traverse()
	temp := ReverseKGroup(first.Head, 3)
        fmt.Println()
	temp.Traverse()

}

func initList() *SingleList {
	return &SingleList{}
}

type ListNode struct {
	Val  int
	Next *ListNode
}

func (l *ListNode) Traverse() {
	for l != nil {
		fmt.Println(l.Val)
		l = l.Next
	}
}

type SingleList struct {
	Len  int
	Head *ListNode
}

func ReverseKGroup(head *ListNode, k int) *ListNode {

	curr := head
	var prev *ListNode
	var next *ListNode

	i := 0

	for curr != nil && i < k {
		i++
		curr = curr.Next
	}
	if i == k {
		curr = head
	} else {
		return head
	}

	i = 0
	for curr != nil && i < k {
		next = curr.Next
		curr.Next = prev
		prev = curr
		curr = next
		i++
	}

	head.Next = ReverseKGroup(curr, k)
	return prev
}

func (s *SingleList) AddFront(num int) {
	ele := &ListNode{
		Val: num,
	}
	if s.Head == nil {
		s.Head = ele
	} else {
		ele.Next = s.Head
		s.Head = ele
	}
	s.Len++
}

输出

1
2
3
4

3
2
1
4

注意: 请查看我们的 Golang 高级教程。本系列教程内容详尽,我们尝试用例子覆盖所有概念。此教程适合希望获得 Golang 专业知识和扎实理解的人 - Golang 高级教程

如果你有兴趣了解如何在 Golang 中实现所有设计模式。如果是,那么这篇文章就是为你准备的 - 所有设计模式 Golang

在 Go (Golang)中反转字符串的元音

来源:golangbyexample.com/reverse-vowels-string-golang/

目录

  • 概述

  • 程序

概述

给定一个字符串。目标是反转该字符串中的所有元音。

示例 1

Input: "simple"
Output: "sempli"

示例 2

Input: "complex"
Output: "cemplox"

程序

以下是相应的程序

package main

import "fmt"

func reverseVowels(s string) string {
	runeS := []rune(s)
	lenS := len(runeS)

	for i, j := 0, lenS-1; i < j; {
		for i < j {
			if !vowel(runeS[i]) {
				i++
			} else {
				break
			}
		}
		if i == j {
			break
		}
		for i < j {
			if !vowel(runeS[j]) {
				j--
			} else {
				break
			}
		}

		if i == j {
			break
		}

		runeS[i], runeS[j] = runeS[j], runeS[i]
		i++
		j--

	}

	return string(runeS)

}

func vowel(s rune) bool {
	if s == 'a' || s == 'e' || s == 'i' || s == 'o' || s == 'u' {
		return true
	}

	if s == 'A' || s == 'E' || s == 'I' || s == 'O' || s == 'U' {
		return true
	}

	return false
}

func main() {
	output := reverseVowels("simple")
	fmt.Println(output)

	output = reverseVowels("complex")
	fmt.Println(output)

}

输出:

sempli
cemplox

注意: 请查看我们的 Golang 高级教程。本系列教程内容详尽,我们尽量涵盖所有概念和示例。此教程适合希望获得 Golang 专业知识和扎实理解的人 - Golang 高级教程

如果你有兴趣了解如何在 Golang 中实现所有设计模式。如果是,那么这篇文章适合你 - 所有设计模式 Golang

另外,请查看我们的系统设计教程系列 - 系统设计教程系列*

在 Go 中反转句子中的单词 (Golang)

来源:golangbyexample.com/reverse-words-sentence-golang/

目录

  • 概述

  • 程序

概述

目标是反转给定句子中的单词

示例

Input: "hello world"
Output: "word hello"

另一个例子。如果输入包含一个单词,则返回该单词。

Input: "hello"
Output: "hello"

这是策略

  • 首先,我们反转整个字符串。因此,对于“hello world”来说,它变成了
"dlrow olleh"
  • 然后我们反转每个单词
"world hello"
  • 我们还需要处理开头或结尾的多余空格。

程序

这是相应的程序。

package main

import (
	"fmt"
	"regexp"
	"strings"
)

func reverseWords(s string) string {

	runeArray := []rune(s)
	length := len(runeArray)

	reverseRuneArray := reverse(runeArray)

	for i := 0; i < length; {
		for i < length && string(reverseRuneArray[i]) == " " {
			i++
		}
		if i == length {
			break
		}
		wordStart := i

		for i < length && string(reverseRuneArray[i]) != " " {
			i++
		}

		wordEnd := i - 1

		reverseRuneArray = reverseIndex(reverseRuneArray, wordStart, wordEnd)

	}

	noSpaceString := strings.TrimSpace(string(reverseRuneArray))
	space := regexp.MustCompile(`\s+`)
	return space.ReplaceAllString(noSpaceString, " ")
}

func reverse(s []rune) []rune {
	length := len(s)
	start := 0
	end := length - 1
	for start < end {
		s[start], s[end] = s[end], s[start]
		start++
		end--
	}
	return s
}

func reverseIndex(s []rune, i, j int) []rune {

	start := i
	end := j
	for start < end {
		s[start], s[end] = s[end], s[start]
		start++
		end--
	}
	return s
}

func main() {
	output := reverseWords("hello world")
	fmt.Println(output)

	output = reverseWords("hello")
	fmt.Println(output)
}

输出

world hello
hello

注意: 请查看我们的 Golang 高级教程。本系列的教程内容详尽,我们尽力涵盖所有概念和示例。本教程适合那些希望获得专业知识和深入理解 Golang 的人 - Golang 高级教程

如果你有兴趣了解所有设计模式如何在 Golang 中实现。如果是的话,那么这篇文章就是为你准备的 - 所有设计模式 Golang*

在 Go(Golang)中旋转链表

来源:golangbyexample.com/rotate-linked-list-golang/

目录

  • 概述

  • 程序

概述

目标是将给定列表按指定数量向右旋转。

示例

Input: 1->2->3->4->5
k: 2

Output: 4->5->1->2->3

程序

这是相应的程序。

package main

import "fmt"

func main() {
	first := initList()
	first.AddFront(5)
	first.AddFront(4)
	first.AddFront(3)
	first.AddFront(2)
	first.AddFront(1)

	first.Head.Traverse()

	head := rotateRight(first.Head, 2)
	fmt.Println("")
	head.Traverse()
	fmt.Println("")

}

func initList() *SingleList {
	return &SingleList{}
}

type ListNode struct {
	Val  int
	Next *ListNode
}

func (l *ListNode) Traverse() {
	for l != nil {
		fmt.Print(l.Val)
		l = l.Next
	}
}

type SingleList struct {
	Len  int
	Head *ListNode
}

func (s *SingleList) Reverse() {

	curr := s.Head
	var prev *ListNode
	var next *ListNode

	for curr != nil {
		next = curr.Next
		curr.Next = prev
		prev = curr
		curr = next
	}
	s.Head = prev
}
func (s *SingleList) AddFront(num int) {
	ele := &ListNode{
		Val: num,
	}
	if s.Head == nil {
		s.Head = ele
	} else {
		ele.Next = s.Head
		s.Head = ele
	}
	s.Len++
}

func rotateRight(head *ListNode, k int) *ListNode {

	if head == nil {
		return nil
	}

	if k == 0 {
		return head
	}

	lenList := 0

	curr := head
	var last *ListNode

	for curr != nil {
		lenList++
		last = curr
		curr = curr.Next
	}

	k = k % lenList
	if k == 0 {
		return head
	}

	curr = head

	newHeadIndex := lenList - k

	var prev *ListNode

	for i := 0; i < newHeadIndex; i++ {
		prev = curr
		curr = curr.Next
	}

	newHeadNode := prev.Next

	prev.Next = nil

	last.Next = head
	return newHeadNode
}

输出

12345
45123

注意: 请查看我们的 Golang 高级教程。本系列教程内容详尽,我们尝试涵盖所有概念及示例。本教程适合那些希望获得专业知识和对 Golang 有深入理解的人 - Golang 高级教程

如果你有兴趣了解所有设计模式如何在 Golang 中实现。如果是,那么这篇文章就是为你准备的 - 所有设计模式 Golang

在 Go (Golang)中顺时针旋转对称矩阵或图像

来源:golangbyexample.com/rotate-image-clockwise-golang/

概述

给定一个以矩阵形式表示的图像,将该矩阵或图像顺时针旋转。

例如

输入:

[[1, 2, 3], 
 [4, 5, 6], 
 [7, 8, 9]]

输出:

7, 4, 1 
8, 5, 2 
9, 6, 3

思路是逐一遍历所有边界,并就地交换每一侧。上述矩阵的外边界是

7 4  1
8     2 
9 6 3

我们可以这样就地旋转矩阵

7->1->3->9
4->2->6->8

一个 n*n 大小的对称矩阵将有n-1个边界。例如,上述矩阵有两个边界

第一个边界

7 4 1
8    2 
9 6 3

第二个边界

5

目录

** 程序

程序

下面是相应的程序

package main

import "fmt"

func main() {
	matrix := [][]int{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}
	rotate(matrix)

	matrix = [][]int{{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 16}}
	rotate(matrix)
}

func rotate(matrix [][]int) {

	matrixSize := len(matrix)

	startRow := 0
	endRow := matrixSize - 1
	startColumn := 0
	endColumn := matrixSize - 1
	for i := 0; i < matrixSize; i++ {
		totalCycles := endRow - startRow

		for j := 0; j < totalCycles; j++ {
			temp := matrix[startRow][startColumn+j]
			matrix[startRow][startColumn+j] = matrix[endRow-j][startColumn]

			matrix[endRow-j][startColumn] = matrix[endRow][endColumn-j]

			matrix[endRow][endColumn-j] = matrix[startRow+j][endColumn]

			matrix[startRow+j][endColumn] = temp
		}

		startRow = startRow + 1
		endRow = endRow - 1
		startColumn = startColumn + 1
		endColumn = endColumn - 1
	}

	fmt.Println(matrix)

}

输出

[[7 4 1] [8 5 2] [9 6 3]]
[[13 9 5 1] [14 10 6 2] [15 11 7 3] [16 12 8 4]]

注意: 请查看我们的 Golang 高级教程。本系列教程内容详尽,我们尽力用例子覆盖所有概念。这个教程适合那些希望获得专业知识和对 Golang 有深入理解的人 - Golang 高级教程

如果你有兴趣了解如何在 Golang 中实现所有设计模式。如果是,那么这篇文章就是为你准备的 - 所有设计模式 Golang

Go 语言中的腐烂橙子程序(Golang)

来源:golangbyexample.com/rotting-oranges-program-go/

目录

  • 概述

  • 程序

概述

给定一个 m*n 矩阵,其中每个条目包含三个值

  • 0 – 表示该条目为空

  • 1 – 表示该条目包含新鲜橙子

  • 2 – 表示该条目包含腐烂的橙子

腐烂的橙子将在 1 天内腐烂相邻的橙子。对于给定的橙子,位于上、下、左和右的任何橙子都是相邻橙子。对角线的橙子不算在内。

目标是找出所有橙子腐烂的天数。如果所有橙子无法腐烂,则写-1。这种情况发生在新鲜橙子无法从腐烂橙子到达时。

示例 1

Input: [[2,1,1],[1,1,0],[0,1,1]]
Output: 4

顶部有一个腐烂的橙子。它将腐烂相邻的两个橙子。这些腐烂的橙子将进一步腐烂它们相邻的橙子。

示例 2

Input: [[1,1]]
Output: -1

程序

下面是相应的程序

package main

import "fmt"

func orangesRotting(grid [][]int) int {
	numRows := len(grid)
	numColumns := len(grid[0])

	queue := make([][2]int, 0)

	for i := 0; i < numRows; i++ {
		for j := 0; j < numColumns; j++ {
			if grid[i][j] == 2 {
				queue = append(queue, [2]int{i, j})
			}
		}
	}

	neighboursIndex := [][2]int{{1, 0}, {-1, 0}, {0, 1}, {0, -1}}
	numMinutes := 0
	for {
		n := len(queue)
		for i := 0; i < n; i++ {
			pop := queue[0]
			queue = queue[1:]

			a := pop[0]
			b := pop[1]
			for k := 0; k < 4; k++ {
				neighbourX := a + neighboursIndex[k][0]
				neighbourY := b + neighboursIndex[k][1]

				if isValid(neighbourX, neighbourY, numRows, numColumns) {
					if grid[neighbourX][neighbourY] == 1 {
						grid[neighbourX][neighbourY] = 2
						queue = append(queue, [2]int{neighbourX, neighbourY})
					}
				}

			}
		}

		if len(queue) == 0 {
			break
		}
		numMinutes++
	}

	for i := 0; i < numRows; i++ {
		for j := 0; j < numColumns; j++ {
			if grid[i][j] == 1 {
				return -1
			}
		}
	}

	return numMinutes
}

func isValid(i, j, numRows, numColumns int) bool {
	if i >= numRows || i < 0 {
		return false
	}

	if j >= numColumns || j < 0 {
		return false
	}
	return true
}

func main() {
	output := orangesRotting([][]int{{2, 1, 1}, {1, 1, 0}, {0, 1, 1}})
	fmt.Println(output)

	output = orangesRotting([][]int{{1, 1}})
	fmt.Println(output)
}

输出:

4
-1

**注意:**查看我们的 Golang 高级教程。本系列的教程内容详尽,我们试图用示例覆盖所有概念。这个教程是为那些希望获得专业知识和对 Golang 有扎实理解的人准备的 - Golang 高级教程

如果你有兴趣了解所有设计模式如何在 Golang 中实现。如果是的话,这篇文章就是为你准备的 - 所有设计模式 Golang

同时,查看我们的系统设计教程系列 - 系统设计教程系列

数据集介绍:自动驾驶多类交通目标检测数据集 一、基础信息 数据集名称:自动驾驶多类交通目标检测数据集 图片数量: - 训练集:2,868张图片 - 验证集:30张图片 - 测试集:301张图片 分类类别: - Bikes(自行车):交通场景中常见非机动车类型 - Bus(公交车):大型公共交通工具 - Car(汽车):主流机动车辆类型 - Crosswalk(人行横道):道路安全标识 - Fire hydrant(消防栓):城市基础设施组件 标注格式: YOLO格式,包含目标检测所需的边界框坐标及类别标签,支持主流深度学习框架。 数据来源:真实道路场景采集,涵盖多样交通环境。 二、适用场景 自动驾驶感知系统开发: 用于训练车辆环境感知模型,精准识别道路参与者(车辆、行人)及关键基础设施(人行道、消防栓)。 智能交通监控系统: 支持开发实时交通流量分析系统,识别车辆类型及道路安全标识。 道路安全研究: 为交叉路口安全分析、基础设施布局优化提供数据支撑。 AI算法基准测试: 适用于目标检测模型性能验证,覆盖常见交通目标类别。 三、数据集优势 场景覆盖全面: 包含5类关键交通要素,覆盖车辆、行人设施及市政设备,满足复杂场景建模需求。 标注质量可靠: 专业团队标注,严格质检流程确保边界框定位精准,类别标注准确。 任务适配性强: 原生YOLO格式支持主流检测框架(YOLOv5/v7/v8等),即插即用。 应用潜力突出: 数据来源于真实道路场景,可直接应用于L2-L4级自动驾驶系统开发,具备强工程落地价值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值