首页 > 其他分享 >Go标准库学习:strings和bytes

Go标准库学习:strings和bytes

时间:2023-11-23 16:33:43浏览次数:56  
标签:string int bytes func Go str01 byte strings

strings包和bytes包

strings包和bytes包非常像,几乎所有函数都有string[]byte两种接口,其中前者被实现在strings包中,而后者被是现在bytes包中,所以这里将这两个包一起学习。

官方文档:

strings包:https://pkg.go.dev/[email protected]

bytes包:https://pkg.go.dev/[email protected]

函数

clone

// strings
func Clone(s string) string
// bytes
func Clone(b []byte) []byte

克隆[]byte和string。默认赋值操作只是浅拷贝,Clone会对[]byte和string进行深拷贝。

func CloneTest() {
	sliceCopyTest()
	sliceCloneTest()
	stringCopyTest()
	stringCloneTest()
}

func sliceCopyTest() {
	bts01 := []byte("testing")
	bts02 := bts01
	fmt.Print("Copy(bts02 := bts01), ")
	bts01[0] = 's'
	fmt.Println("bts01[0] = 's':")
	fmt.Printf("bts01 = %q, bts02 = %q\n", bts01, bts02)
	fmt.Println()
}

func sliceCloneTest() {
	bts01 := []byte("testing")
	bts02 := bytes.Clone(bts01)
	fmt.Print("Copy(bts02 := bytes.Clone(bts01)), ")
	bts01[0] = 's'
	fmt.Println("bts01[0] = 's':")
	fmt.Printf("bts01 = %q, bts02 = %q\n", bts01, bts02)
	fmt.Println()
}

func stringCopyTest() {
	str01 := "testing"
	str02 := str01
	fmt.Println("str02 := str01:")
	fmt.Printf("unsafe.StringData(str01) == unsafe.StringData(str02): %v\n", unsafe.StringData(str01) == unsafe.StringData(str02))
	fmt.Println()
}

func stringCloneTest() {
	str01 := "testing"
	str02 := strings.Clone(str01)
	fmt.Println("str02 := strings(str01):")
	fmt.Printf("unsafe.StringData(str01) == unsafe.StringData(str02): %v\n", unsafe.StringData(str01) == unsafe.StringData(str02))
	fmt.Println()
}

/*
Output:
Copy(bts02 := bts01), bts01[0] = 's':
bts01 = "sesting", bts02 = "sesting"

Copy(bts02 := bytes.Clone(bts01)), bts01[0] = 's':
bts01 = "sesting", bts02 = "testing"

str02 := str01:
unsafe.StringData(str01) == unsafe.StringData(str02): true

str02 := strings(str01):
unsafe.StringData(str01) == unsafe.StringData(str02): false
*/

内容检查类的函数,是否包含。Contains/Has.

// strings
// s中是否包含substr
func Contains(s, substr string) bool
// s中是否包含r
func ContainsRune(s string, r rune) bool
// s中是否包含任何chars中的rune
func ContainsAny(s, chars string) bool
// 对s中的所有rune调用f,是否有一个调用结果为true
func ContainsFunc(s string, f func(rune) bool) bool
// s中是否有前缀prefix
func HasPrefix(s, prefix string) bool
// s中是否有后缀suffix
func HasSuffix(s, suffix string) bool

// bytes
func Contains(b, subslice []byte) bool
func ContainsRune(b []byte, r rune) bool
func ContainsAny(b []byte, chars string) bool // 注意,chars类型为string
func ContainsFunc(b []byte, f func(rune) bool) bool
func HasPrefix(s, prefix []byte) bool
func HasSuffix(s, suffix []byte) bool

测试:

func ContainsAndHasTest() {
	str01 := "“你好”是一个很好的词汇"
	fmt.Println(strings.Contains(str01, "词汇"))      // true
	fmt.Println(strings.ContainsAny(str01, "词语"))   // true
	fmt.Println(strings.ContainsRune(str01, '你'))    // true
	fmt.Println(strings.ContainsFunc(str01, func(r rune) bool { return r == '你' || r == '我' })) // true
	fmt.Println(strings.HasPrefix(str01, "“你好"))    // true
	fmt.Println(strings.HasSuffix(str01, "词汇"))     // true
	fmt.Println()
}

Count

// strings
func Count(s, substr string) int
// bytes
func Count(s, sep []byte) int

获取字串在s中的数量,字串为空串则返回1 + s中unicode码点的数量

获取字串的下标 Index

// strings
// 字串在s中的下标(in byte)
func Index(s, substr string) int
// unicode码点r在s中的第一个下标,r不是一个合法的码点则返回第一个非法码点的下标
func IndexRune(s string, r rune) int
// 字节c在s中的第一个下标
func IndexByte(s string, c byte) int
// chars中任意一个rune出现在s中的第一个下标
func IndexAny(s, chars string) int
// s中的rune r,使得f(r)为真的第一个rune的下标
func IndexFunc(s string, f func(rune) bool) int

// 最后一个下标的版本,注意,没有IndexLastRune这个函数
func LastIndex(s, substr string) int
func LastIndexAny(s, chars string) int
func LastIndexByte(s string, c byte) int
func LastIndexFunc(s string, f func(rune) bool) int

// bytes
func Index(s, sep []byte) int
func IndexAny(s []byte, chars string) int
func IndexByte(b []byte, c byte) int
func IndexFunc(s []byte, f func(r rune) bool) int
func IndexRune(s []byte, r rune) int
func LastIndex(s, sep []byte) int
func LastIndexAny(s []byte, chars string) int
func LastIndexByte(s []byte, c byte) int
func LastIndexFunc(s []byte, f func(r rune) bool) int

获取string/[]byte中rune/byte/string/[]byte的下标/最后一个下标的函数

func IndexTest() {
	str01 := "你好你好你呀"
	str02 := "好你"
	fmt.Printf("Index(%q, %q) = %d\n", str01, str02, strings.Index(str01, str02))
	fmt.Printf("IndexByte(%q, %q) = %d\n", str01, str02[0], strings.IndexByte(str01, str02[0]))
	r, _ := utf8.DecodeRuneInString(str02)
	fmt.Printf("IndexRune(%q, %q) = %d\n", str01, r, strings.IndexRune(str01, r))
	fmt.Printf("IndexAny(%q, %q) = %d\n", str01, str02, strings.IndexAny(str01, str02))
	isNi := func(r rune) bool { return r == '你' }
	fmt.Printf("IndexFunc(%q, isNi) = %d\n", str01, strings.IndexFunc(str01, isNi))

	fmt.Printf("LastIndex(%q, %q) = %d\n", str01, str02, strings.LastIndex(str01, str02))
	fmt.Printf("LastIndexByte(%q, %q) = %d\n", str01, str02[0], strings.LastIndexByte(str01, str02[0]))
	// fmt.Printf("LastIndexRune(%q, %q) = %d\n", str01, r, strings.LastIndexRune(str01, r)) // No Such Function
	fmt.Printf("LastIndexAny(%q, %q) = %d\n", str01, str02, strings.LastIndexAny(str01, str02))
	fmt.Printf("LastIndexFunc(%q, isNi) = %d\n", str01, strings.LastIndexFunc(str01, isNi))
}

/*
Output:
Index("你好你好你呀", "好你") = 3
IndexByte("你好你好你呀", 'å') = 3
IndexRune("你好你好你呀", '好') = 3
IndexAny("你好你好你呀", "好你") = 0
IndexFunc("你好你好你呀", isNi) = 0
LastIndex("你好你好你呀", "好你") = 9
LastIndexByte("你好你好你呀", 'å') = 15
LastIndexAny("你好你好你呀", "好你") = 12
LastIndexFunc("你好你好你呀", isNi) = 12
*/

相等性测试

// strings
// string的相等性测试可以直接使用 == 操作符
// 在unicode字符集中忽略大小写进行比较,更加通用
func EqualFold(s, t string) bool

// bytes
// a和b是否长度相同且内容相同
func Equal(a, b []byte) bool
func EqualFold(s, t []byte) bool

Equal是相等性测试,EqualFold是忽略大小写的相等性测试。

// 用泛型实现Equal
func Equal[T comparable](a, b []T) bool {
	if len(a) != len(b) {
		return false
	}
	for i := 0; i < len(a); i++ {
		if a[i] != b[i] {
			return false
		}
	}
	return true
}

func EqualTest() {
	strSlice := []string{"abc", "def", "你好"}
	strSlice2 := []string{"abc", "def", "你好"}
	byteSlice := []byte{1, 2, 3, 4, 5}
	byteSlice2 := []byte{1, 2, 3, 4, 5}
	fmt.Printf("Equal(%q, %q) = %v\n", strSlice, strSlice2, Equal(strSlice, strSlice2))
	fmt.Printf("Equal(%q, %q) = %v\n", byteSlice, byteSlice2, Equal(byteSlice, byteSlice2))
}
/*
Output:
Equal(["abc" "def" "你好"], ["abc" "def" "你好"]) = true
Equal("\x01\x02\x03\x04\x05", "\x01\x02\x03\x04\x05") = true
*/

去掉前缀、后缀,分割等函数

// strings
// 按照sep,将s分割为 before、sep、after,如果sep在s中不存在,返回s, "", false
func Cut(s, sep string) (before, after string, found bool)
// 如果prefix是s的前缀,返回s[len(prefix):],true,s中没有prefix则返回s,false,prefix为空则返回s,true
func CutPrefix(s, prefix string) (after string, found bool)
// 剪除后缀
func CutSuffix(s, suffix string) (before string, found bool)
// 按照sep将s分割
// If s does not contain sep and sep is not empty, Split returns a slice of length 1 whose only element is s.
// If sep is empty, Split splits after each UTF-8 sequence. 
// If both s and sep are empty, Split returns an empty slice.
func Split(s, sep string) []string
// 最多划分为n个substring
// n > 0: at most n substrings; the last substring will be the unsplit remainder.
// n == 0: the result is nil (zero substrings)
// n < 0: all substrings
func SplitN(s, sep string, n int) []string
// sep不会被丢弃,而是放在被分割的字串后面
func SplitAfter(s, sep string) []string
// 最多划分为n个字串
func SplitAfterN(s, sep string, n int) []string
// 按照空白字符将s分割为slice,空白字符的判断标准为unicode.IsSpace()
func Fields(s string) []string
// 按照f(r)的结果将s分割为slice,Fields等效于FieldsFunc(s, unicode.IsSpace)
func FieldsFunc(s string, f func(rune) bool) []string
// 从前面和后面删除连续的cutset中的unicode码点,然后返回s的slice
func Trim(s, cutset string) string
// 从前面和后面删除连续的空白字符,相等于TrimFunc(s, unicode.isSpace)
func TrimSpace(s string) string
// 从s前面和后面删除连续的使得f(r)为真的unicode码点,然后返回s的slice
func TrimFunc(s string, f func(rune) bool) string
// 从s前面删除连续的cutset中的unicode码点,然后返回s的slice
func TrimLeft(s, cutset string) string
// 从s后面删除连续的cutset中的unicode码点,然后返回s的slice
func TrimRight(s, cutset string) string
// 从s前面删除连续的使得f(r)为真的unicode码点,然后返回s的slice
func TrimLeftFunc(s string, f func(rune) bool) string
// 从s前面删除连续的使得f(r)为真的unicode码点,然后返回s的slice
func TrimRightFunc(s string, f func(rune) bool) string
// 如果s的前缀是prefix,则删除该前缀,返回s的slice;否则返回s
func TrimPrefix(s, prefix string) string
// 如果s的后缀是suffix,则删除该后缀,返回s的slice,否则返回s
func TrimSuffix(s, suffix string) string


// bytes
func Cut(s, sep []byte) (before, after []byte, found bool)
func CutPrefix(s, prefix []byte) (after []byte, found bool)
func CutSuffix(s, suffix []byte) (before []byte, found bool)
func Split(s, sep []byte) [][]byte
func SplitAfter(s, sep []byte) [][]byte
func SplitAfterN(s, sep []byte, n int) [][]byte
func SplitN(s, sep []byte, n int) [][]byte
func Fields(s []byte) [][]byte
func FieldsFunc(s []byte, f func(rune) bool) [][]byte
func Trim(s []byte, cutset string) []byte
func TrimFunc(s []byte, f func(r rune) bool) []byte
func TrimLeft(s []byte, cutset string) []byte
func TrimLeftFunc(s []byte, f func(r rune) bool) []byte
func TrimPrefix(s, prefix []byte) []byte
func TrimRight(s []byte, cutset string) []byte
func TrimRightFunc(s []byte, f func(r rune) bool) []byte
func TrimSpace(s []byte) []byte
func TrimSuffix(s, suffix []byte) []byte

重复字符串

// strings
// 返回count个s首尾相连组成的字符串,count < 0是出错
func Repeat(s string, count int) string

// bytes
func Repeat(b []byte, count int) []byte

单纯的将s重复几次

替换字符串/转换字符串

// strings
// 将s中的每个字符使用mapping函数替换,返回拷贝。如果mapping函数返回一个负值,函数会丢弃该字符
func Map(mapping func(rune) rune, s string) string
// 将s中n个不重叠的old字符串替换为new字符串,n < 0时替换所有字符串
//  old为空时在每个unicode码点之间(包括最开始和最后)添加new对应的字符串,最多替换n个
func Replace(s, old, new string, n int) string
// 等于Replace(s, old, new, -1)
func ReplaceAll(s, old, new string) string
// 将s中的unicode码点转化为小写
func ToLower(s string) string
// 部分语言有特殊的大小写映射,ToLowerSprcial方法优先处理这些特殊的大小写映射
func ToLowerSpecial(c unicode.SpecialCase, s string) string
// 将s中的unicode码点转化为标题格式,目前来看英文转化为全大写,中文不变
func ToTitle(s string) string
// 部分语言有特殊的标题格式映射
func ToTitleSpecial(c unicode.SpecialCase, s string) string
// 转化为大写
func ToUpper(s string) string
// 部分语言有特殊的大小写映射
func ToUpperSpecial(c unicode.SpecialCase, s string) string
// 将s中非法的utf8字节序列替换为replacement
func ToValidUTF8(s, replacement string) string

// bytes
func Map(mapping func(r rune) rune, s []byte) []byte
func Replace(s, old, new []byte, n int) []byte
func ReplaceAll(s, old, new []byte) []byte
// 将s中的字节解读为unicode码点
func Runes(s []byte) []rune
func ToLower(s []byte) []byte
func ToLowerSpecial(c unicode.SpecialCase, s []byte) []byte
func ToTitle(s []byte) []byte
func ToTitleSpecial(c unicode.SpecialCase, s []byte) []byte
func ToUpper(s []byte) []byte
func ToUpperSpecial(c unicode.SpecialCase, s []byte) []byte
func ToValidUTF8(s, replacement []byte) []byte

这部分是关于字符串/[]byte的替换/转换的函数,针对的都是字符串,针对单个unicode码点(rune类型)的操作(比如IsUpper, IsSpace, ToUpper)在unicode库中。

类型(type)

用于构建string的类

因为string是不可变类型,在用+操作符构建string时每一次都要分配一次内存,导致效率低下。

所以go标准库提供了高效构建string的类。

Builder类

// strings
type Builder struct {
	// contains filtered or unexported fields
}

Builder类型是strings包提供的,用于高效构建string的类,其会最小化内存拷贝。

不要拷贝非零的Builder对象。

Builder类的成员方法

func (b *Builder) Len() int

builder已经写入的字节数;b.Len() = len(b.String())

func (b *Builder) Cap() int

获取该builder已经分配的,用于构建string的空间,包括已经写入的空间。

func (b *Builder) Grow(n int)

增长builder的容量,使其至少能再写入n个字节,而不用再次分配内存。

func (b *Builder) Reset()

清空builder已经写入的内容

func (b *Builder) String() string

返回累加的string

func (b *Builder) Write(p []byte) (int, error)
func (b *Builder) WriteByte(c byte) error
func (b *Builder) WriteRune(r rune) (int, error)
func (b *Builder) WriteString(s string) (int, error)

向builder中写入内容。

Buffer类

type Buffer struct {
	// contains filtered or unexported fields
}

Buffer是bytes包提供的高效的string构建类,其比Builder更加强大。Builder的读出操作只有String()方法,Buffer支持更多的读出方法。

与Buffer类相关的函数

func NewBuffer(buf []byte) *Buffer
func NewBufferString(s string) *Buffer

分别以[]byte和string的内容为基础构建新的Buffer类实例。

大多数情况下,new(Buffer)(或者直接定义一个Buffer类型的变脸)就可以初始化一个空的Buffer。

Buffer类的成员方法

func (b *Buffer) Available() int
func (b *Buffer) Cap() int
func (b *Buffer) Len() int

空间大小相关的函数。
Cap()返回Buffer的内部空间的容量。
Available()返回还未使用的,但已经申请的空间的大小。
Len()返回写入后未读出的空间的大小。

func (b *Buffer) Grow(n int)

使得Buffer至少能再读入n个字节而不重新分配内存。

func (b *Buffer) Truncate(n int)

除了前n个未读的字节外,丢弃其他已写入的字节,不会重新分配内存。

func (b *Buffer) ReadFrom(r io.Reader) (n int64, err error)
func (b *Buffer) Write(p []byte) (n int, err error)
func (b *Buffer) WriteByte(c byte) error
func (b *Buffer) WriteRune(r rune) (n int, err error)
func (b *Buffer) WriteString(s string) (n int, err error)

向Buffer中写入内容。

strings.Builder不同的是有一个ReadFrom()方法,该方法从一个io.Reader(这是一个接口,包含Read()方法)中读取内容,并返回读取的字节数量和出现的错误(io.EOF不视为错误,io.ReaderRead()方法返回io.EOFReadFrom()方法不会返回错误)。

func (b *Buffer) Bytes() []byte
func (b *Buffer) Read(p []byte) (n int, err error)
func (b *Buffer) ReadByte() (byte, error)
func (b *Buffer) ReadBytes(delim byte) (line []byte, err error)
func (b *Buffer) ReadRune() (r rune, size int, err error)
func (b *Buffer) ReadString(delim byte) (line string, err error)
func (b *Buffer) String() string
func (b *Buffer) WriteTo(w io.Writer) (n int64, err error)

Buffer类中有众多的读出方式,包括读取全部字节、读指定数量的字节、读一个字节、读到某个字节为止、读一个unicode码点、全部都出来作为一个string

同时Buffer类还有一个与ReadFrom()对应的方法WriteTo(),该方法将字节写入到一个io.Writer(这是一个接口,包含Write()方法)中,并返回写入的字节数和出现的错误。

func (b *Buffer) AvailableBuffer() []byte

返回未写入的空闲的空间,直到下次写入操作前该空间都有效。

func (b *Buffer) UnreadByte() error
func (b *Buffer) UnreadRune() error

将上次读取的byte/rune回退到缓冲区中。

用于读取string/[]byte的类

有时候我们需要将string/[]byte当作输入,strings和bytes包中都提供了名为Reader的类,用于将string/[]byte作为输入源。

strings.Reader

type Reader struct {
	// contains filtered or unexported fields
}

实现了io.Reader, io.ReaderAt, io.ByteReader, io.ByteScanner, io.RuneReader, io.RuneScanner, io.Seeker, io.WriterTo接口,使用string作为输入源,零值的行为与以空字符串初始化相同。

strings.Reader相关函数

func NewReader(s string) *Reader

s为输入源创建一个strings.Reader

成员函数

func (r *Reader) Len() int // 返回还未读出的字节的数量
func (r *Reader) Read(b []byte) (n int, err error)
func (r *Reader) ReadAt(b []byte, off int64) (n int, err error)
func (r *Reader) ReadByte() (byte, error)
func (r *Reader) ReadRune() (ch rune, size int, err error)
func (r *Reader) Reset(s string) // 重置,再次从头开始读
func (r *Reader) Seek(offset int64, whence int) (int64, error) // 重新定位到某个地方,实现了io.Seeker接口
func (r *Reader) Size() int64 // 返回字符串s的初始长度
func (r *Reader) UnreadByte() error
func (r *Reader) UnreadRune() error
func (r *Reader) WriteTo(w io.Writer) (n int64, err error)

大部分语义和前面的一样,没见过的加了注释。

bytes.Reader

type Reader struct {
	// contains filtered or unexported fields
}

strings.Reader类似,只不过使用[]byte作为输入源。

相关函数

func NewReader(b []byte) *Reader

成员函数

func (r *Reader) Len() int
func (r *Reader) Read(b []byte) (n int, err error)
func (r *Reader) ReadAt(b []byte, off int64) (n int, err error)
func (r *Reader) ReadByte() (byte, error)
func (r *Reader) ReadRune() (ch rune, size int, err error)
func (r *Reader) Reset(b []byte)
func (r *Reader) Seek(offset int64, whence int) (int64, error)
func (r *Reader) Size() int64
func (r *Reader) UnreadByte() error
func (r *Reader) UnreadRune() error
func (r *Reader) WriteTo(w io.Writer) (n int64, err error)

strings.Replacer

type Replacer struct {
	// contains filtered or unexported fields
}

用于方便地替换string中的内容的辅助类,看后面的例子就明白了。

相关函数

func NewReplacer(oldnew ...string) *Replacer

以old1, new1, old2, new2...的顺序构建Replacer,表示将后续的字符串中的所有的old1/old2/...替换为new1/new2/...

例子:

package main

import (
	"fmt"
	"strings"
)

func main() {
	r := strings.NewReplacer("<", "&lt;", ">", "&gt;")
	fmt.Println(r.Replace("This is <b>HTML</b>!"))
}
// 官网示例,在我的go version go1.21.4 linux/amd64中没问题。
/*
Output:
This is &lt;b&gt;HTML&lt;/b&gt;!
*/

成员函数

func (r *Replacer) Replace(s string) string

s按照预定义的规则替换,返回替换后的字符串。

func (r *Replacer) WriteString(w io.Writer, s string) (n int, err error)

将替换后的字符串写入w

标签:string,int,bytes,func,Go,str01,byte,strings
From: https://www.cnblogs.com/lycpp/p/17851887.html

相关文章

  • golang常用包详解之: errgroup
    前言:并发编程在现代软件开发中变得越来越重要。Go语言通过goroutine和channel等语言特性为并发编程提供了非常强大的支持,但是在实际开发中,如何有效管理多个goroutine并处理它们可能产生的错误是一个挑战。这时,Go语言的官方库中的errgroup包就能发挥作用。正文:1.errgroup包概述......
  • Golang Gin 请求参数的获取值 & 路由分组 & 控制器继承
    一. 请求参数的获取值  动态路由1typeUserstruct{2Usernamestring`form:"username"json:"username"`3Passwordstring`form:"password"json:"password"`4Ageint`form:"age"json:"......
  • go使用snmp库查询mib数据
    OID(ObjectIdentifier)是一种用于标识和唯一命名管理信息库中的对象的标准方式。给定一个OID,可以确定特定的管理信息库对象,并对其进行操作。go语言使用snmp库中的k-sone/snmpgo实现相关mib查询的代码如下:packagemainimport("fmt""log""net""gith......
  • 玩转开源 | 搭建 Hugo 管理 Markdown 文档
    在工作、学习中,不可避免会要写一些文档;又或者想搭建个简单网站,记录和分享您的生活经验或知识;撰写这些文档中使用markdown是一个非常不错的选择,让我们更加聚焦在文档表达的内容上。实际上笔者的文档基本都是在Sublime中用markdown格式撰写的。在先前文章《Markdown的那些......
  • gobgp宣告bgp路由
    wgethttps://github.com/osrg/gobgp/releases/download/v3.20.0/gobgp_3.20.0_linux_amd64.tar.gz#c1和c2容器启动gobgpd守护进程#c1#gobgpd.conf[global.config]as=1002router-id="172.17.0.4"[[neighbors]][neighbors.config]peer-as=1002......
  • 基于googlenet网络的动物种类识别算法matlab仿真
    1.算法运行效果图预览   2.算法运行软件版本matlab2022a 3.算法理论概述       动物种类识别算法基于深度学习技术,尤其是卷积神经网络(CNN),如GoogleNet。这种算法的主要原理是通过学习和识别图像中的特征来预测动物的种类。        GoogleNet,也被......
  • 2023-11-22:用go语言,给你一个长度为 n 下标从 0 开始的整数数组 nums。 它包含 1 到 n
    2023-11-22:用go语言,给你一个长度为n下标从0开始的整数数组nums。它包含1到n的所有数字,请你返回上升四元组的数目。如果一个四元组(i,j,k,l)满足以下条件,我们称它是上升的:0<=i<j<k<l<n且nums[i]<nums[k]<nums[j]<nums[l]。输入:nums=[1,3,2,......
  • 原生sql(django-orm如何执行原生sql)、flask-sqlalchemy使用、flask-migrate使用、
    原生sql(django-orm如何执行原生sql)django执行原生sqlimportosos.environ.setdefault('DJANGO_SETTINGS_MODULE','djangoProject2.settings')importdjangodjango.setup()fromapp01.modelsimportBook,User#原生sql,方式一,跟对象做映射:#book_list=Book.ob......
  • golang 内存分配
    golang的内存分配思想从tcmalloc而来,思路是把对象分配成小对象减少锁的力度或无锁增加效率定义golang内部的页(Page)大小为8B空间大小golang内部把要申请或使用的空间大小分为了三大类:微对象(<16B),小对象(16B~32KB),大对象(>32KB),其中小对象又分为67种,定义在src......
  • golang 原子操作
    在golang中,有原子包,能够实现原子操作,在我分析和猜想下,感觉解开了谜团具体用法不说了,网上一大堆什么cas,add,load,store等,主要是底层实现arm架构在amd架构下,通过汇编指令加锁来实现代码在src/runtime/internal/atomic/atomic_amd64.s//uint64Xadd64(uint64volatile*va......