欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Golang切片連接成字符串的實(shí)現(xiàn)示例

 更新時(shí)間:2023年11月09日 09:55:38   作者:戀喵大鯉魚  
本文主要介紹了Golang切片連接成字符串的實(shí)現(xiàn)示例,可以使用Go語言中的內(nèi)置函數(shù)"String()"可以將字節(jié)切片轉(zhuǎn)換為字符串,具有一定的參考價(jià)值,感興趣的可以了解一下

1.問題

如何將一個(gè)切片連接成一個(gè)字符串呢?

您最先想到的可能是標(biāo)準(zhǔn)庫 strings 包的 Join 函數(shù)。

func Join(elems []string, sep string) string

Join 將字符串切片的所有元素連接成一個(gè)字符串,各個(gè)元素間使用給定的字符串分隔。

package main

import (
	"fmt"
	"strings"
)

func main() {
	s := []string{"foo", "bar", "baz"}
	fmt.Println(strings.Join(s, ", "))
}

運(yùn)行輸出:

foo, bar, baz

strings.Join 只能將字符串切片連接成字符串,但對(duì)于其他類型的切片呢?

事實(shí)上,標(biāo)準(zhǔn)庫并沒有針對(duì)每種類型的切片都給出一個(gè)實(shí)現(xiàn),也沒有使用反射給出一個(gè)通用的實(shí)現(xiàn)。既然沒有那我們自己來實(shí)現(xiàn)一個(gè)吧。

2.使用反射實(shí)現(xiàn)

如果想要將任意類型的切片連接成字符串,可以使用反射(reflect)包來動(dòng)態(tài)處理不同類型的切片,將元素轉(zhuǎn)換為字符串,并連接成一個(gè)字符串。

// JoinE concatenates all elements of Array, Slice or String to a single string with a separator
// and returns an error if an error occurred.
// E.g. input []int{1, 2, 3} and separator ",", output is a string "1,2,3".
// It panics if a's Kind is not Array, Slice, or String.
func JoinE(a any, sep string) (string, error) {
	v := reflect.ValueOf(a)
	if v.Kind() == reflect.String {
		return JoinE(strings.Split(a.(string), ""), sep)
	}
	var s string
	for i := 0; i < v.Len(); i++ {
		if len(s) > 0 {
			s += sep
		}
		str, err := conv.ToStringE(v.Index(i).Interface())
		if err != nil {
			return "", err
		}
		s += str
	}
	return s, nil
}

其中 ToStringE 是將任意類型轉(zhuǎn)為字符串。

// ToStringE casts any type to a string type.
func ToStringE(i any) (string, error) {
	i = indirectToStringerOrError(i)

	switch s := i.(type) {
	case string:
		return s, nil
	case bool:
		return strconv.FormatBool(s), nil
	case int:
		return strconv.Itoa(s), nil
	case int64:
		return strconv.FormatInt(s, 10), nil
	case int32:
		return strconv.Itoa(int(s)), nil
	case int16:
		return strconv.FormatInt(int64(s), 10), nil
	case int8:
		return strconv.FormatInt(int64(s), 10), nil
	case uint:
		return strconv.FormatUint(uint64(s), 10), nil
	case uint64:
		return strconv.FormatUint(uint64(s), 10), nil
	case uint32:
		return strconv.FormatUint(uint64(s), 10), nil
	case uint16:
		return strconv.FormatUint(uint64(s), 10), nil
	case uint8:
		return strconv.FormatUint(uint64(s), 10), nil
	case float64:
		return strconv.FormatFloat(s, 'f', -1, 64), nil
	case float32:
		return strconv.FormatFloat(float64(s), 'f', -1, 32), nil
	case json.Number:
		return s.String(), nil
	case []byte:
		return string(s), nil
	case template.HTML:
		return string(s), nil
	case template.HTMLAttr:
		return string(s), nil
	case template.URL:
		return string(s), nil
	case template.JS:
		return string(s), nil
	case template.JSStr:
		return string(s), nil
	case template.CSS:
		return string(s), nil
	case template.Srcset:
		return string(s), nil
	case nil:
		return "", nil
	case fmt.Stringer:
		return s.String(), nil
	case error:
		return s.Error(), nil
	default:
		return "", fmt.Errorf("unable to cast %#v of type %T to string", i, i)
	}
}

// Copied from html/template/content.go.
// indirectToStringerOrError returns the value, after dereferencing as many times
// as necessary to reach the base type (or nil) or an implementation of fmt.Stringer
// or error.
func indirectToStringerOrError(a any) any {
	if a == nil {
		return nil
	}
	v := reflect.ValueOf(a)
	for !v.Type().Implements(fmtStringerType) && !v.Type().Implements(errorType) && v.Kind() == reflect.Pointer && !v.IsNil() {
		v = v.Elem()
	}
	return v.Interface()
}

如果不關(guān)心錯(cuò)誤,可以再封裝一下。

// Join concatenates all elements of Array, Slice or String to a single string with a separator.
func Join(a any, sep string) string {
	s, _ := JoinE(a, sep)
	return s
}

我們使用不同類型的切片來驗(yàn)證一下。

package main

import (
	"fmt"
	"strings"
)

func main() {
	s := []string{"foo", "bar", "baz"}
	fmt.Println(Join(s, ", "))
	
	i := []int{1, 2, 3}
	fmt.Println(Join(i, ", "))

	f := []float64{1.1, 2.2, 3.3}
	fmt.Println(Join(f, ", "))
	
	b := []bool{true, false, true}
	fmt.Println(Join(b, ", "))

	// 可以將字符串看成字符切片。
	str := "foo"
	fmt.Println(Join(str, ", "))
}

運(yùn)行輸出:

foo, bar, baz
1, 2, 3
1.1, 2.2, 3.3
true, false, true
f, o, o

輸出符合預(yù)期,我們通過反射,只用一個(gè)函數(shù)便可將任意類型的切片連接成字符串。

3.dablelv/cyan

以上代碼已放到開源 Go 工具函數(shù)庫 dablelv/cyan,可直接通過 go mod 方式進(jìn)行 import 然后使用。

歡迎大家協(xié)同共建該工具函數(shù)庫。

import (
	"github.com/dablelv/cyan/str"
)

str.Join([]string{"foo", "bar", "baz"}, ", ")
str.Join([]int{1, 2, 3}, ", ")
str.Join([]float64{1.1, 2.2, 3.3}, ", ")
str.Join([]bool{true, false, true}, ", ")
str.Join("foo", ", ")

4.小結(jié)

對(duì)于字符串切片可以使用標(biāo)準(zhǔn)庫 strings.Join 函數(shù),對(duì)于其他任意類型的切片,利用 Golang 提供的反射能力,在運(yùn)行時(shí)將切片元素轉(zhuǎn)換為字符串并連接到一起。

參考文獻(xiàn)

strings - Go Packages

github.com/dablelv/go-huge-util

到此這篇關(guān)于Golang切片連接成字符串的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)Golang切片連接成字符串內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 解析GOROOT、GOPATH、Go-Modules-三者的關(guān)系

    解析GOROOT、GOPATH、Go-Modules-三者的關(guān)系

    這篇文章主要介紹了解析GOROOT、GOPATH、Go-Modules-三者的關(guān)系,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-10-10
  • go?defer避坑指南之拆解延遲語句

    go?defer避坑指南之拆解延遲語句

    這篇文章主要為大家詳細(xì)介紹了go?defer避坑指南之如何拆解延遲語句,掌握正確使用方法,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-11-11
  • golang語言中wasm 環(huán)境搭建的過程詳解

    golang語言中wasm 環(huán)境搭建的過程詳解

    將 golang 打包為 WASM,通常有兩種打包方式,一種是 golang 自帶的,另外是使用 tinygo ,接下來通過本文給大家介紹golang語言中wasm 環(huán)境搭建的過程,感興趣的朋友一起看看吧
    2021-11-11
  • golang?recover函數(shù)使用中的一些坑解析

    golang?recover函數(shù)使用中的一些坑解析

    這篇文章主要為大家介紹了golang?recover函數(shù)使用中的一些坑解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • goland?-sync/atomic原子操作小結(jié)

    goland?-sync/atomic原子操作小結(jié)

    這篇文章主要介紹了goland?-sync/atomic原子操作,原子操作能夠保證執(zhí)行期間是連續(xù)且不會(huì)被中斷(變量不會(huì)被其他修改,mutex可能存在被其他修改的情況),本文給大家介紹的非常詳細(xì),需要的朋友參考下
    2022-08-08
  • Go實(shí)現(xiàn)SMTP郵件發(fā)送訂閱功能(包含163郵箱、163企業(yè)郵箱、谷歌gmail郵箱)

    Go實(shí)現(xiàn)SMTP郵件發(fā)送訂閱功能(包含163郵箱、163企業(yè)郵箱、谷歌gmail郵箱)

    這篇文章給大家介紹了Go實(shí)現(xiàn)SMTP郵件發(fā)送訂閱功能(包含163郵箱、163企業(yè)郵箱、谷歌gmail郵箱),需求很簡(jiǎn)單,就是用戶輸入自己的郵箱后,使用官方郵箱給用戶發(fā)送替郵件模版,文中有詳細(xì)的代碼示例供大家參考,需要的朋友可以參考下
    2023-10-10
  • golang中命令行庫cobra的使用方法示例

    golang中命令行庫cobra的使用方法示例

    這篇文章主要給大家介紹了關(guān)于golang中命令行庫cobra的使用方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-08-08
  • Go語言 init函數(shù)的具體使用

    Go語言 init函數(shù)的具體使用

    init()函數(shù)是Go語言中一種特殊的函數(shù),用于在包被導(dǎo)入時(shí)執(zhí)行一次性的初始化操作,本文就來介紹一下Go語言 init函數(shù)的具體使用,感興趣的可以了解一下
    2024-09-09
  • 基于Golang?container/list實(shí)現(xiàn)LRU緩存

    基于Golang?container/list實(shí)現(xiàn)LRU緩存

    Least?Recently?Used?(LRU)?,即逐出最早使用的緩存,這篇文章主要為大家介紹了如何基于Golang?container/list實(shí)現(xiàn)LRU緩存,感興趣的可以了解下
    2023-08-08
  • 一文帶你深入理解Go語言中的sync.Cond

    一文帶你深入理解Go語言中的sync.Cond

    sync.Cond?表示的是條件變量,它是一種同步機(jī)制,用來協(xié)調(diào)多個(gè)?goroutine?之間的同步。本文將通過示例為大家介紹Go語言中sync.Cond的使用,需要的可以參考一下
    2023-01-01

最新評(píng)論