最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

GO語(yǔ)言處理多個(gè)布爾選項(xiàng)的實(shí)現(xiàn)過(guò)程

 更新時(shí)間:2026年06月23日 08:59:33   作者:龍門(mén)吹雪  
這段文章詳細(xì)介紹了在Go語(yǔ)言中使用位運(yùn)算和Flags常量高效管理多個(gè)布爾配置參數(shù)的方法,通過(guò)位運(yùn)算實(shí)現(xiàn)高效存儲(chǔ)、組合與檢查,相比傳統(tǒng)方法節(jié)省內(nèi)存并提升性能若您正在處理類(lèi)似需求,此方案值得嘗試

一、需求背景

在 go 語(yǔ)言開(kāi)發(fā)中,經(jīng)常會(huì)遇到類(lèi)似下面需要定義多個(gè)布爾類(lèi)型參數(shù)的場(chǎng)景:

  • 日志打印方式配置參數(shù),包含是否打印文件名、是否打印事件、是否打印函數(shù)名等
  • 打開(kāi)文件的方式參數(shù),包含是否只讀、是否只寫(xiě)、是否創(chuàng)建、是否追加等

實(shí)現(xiàn)上述需求,常規(guī)的做法是定義多個(gè)布爾類(lèi)型的參數(shù),如:

// 文件操作配置類(lèi)
type Config struct {
    IsReadOnly   bool
    IsWriteOnly  bool
    IsCreate     bool
    // ... 每個(gè)標(biāo)志都需要一個(gè)字段
}

上述方案的缺點(diǎn):

  • 占用內(nèi)存多
  • 不便于傳參

二、實(shí)現(xiàn)方案

2.1 方案思路

在 go 語(yǔ)言中,一種更高效的實(shí)現(xiàn)方案是通過(guò)定義常量并使用位運(yùn)算組合多個(gè)布爾選項(xiàng),每個(gè)選項(xiàng)對(duì)應(yīng)一個(gè)二進(jìn)制位(bit),即一個(gè)布爾標(biāo)志

// 文件操作類(lèi)型常量,按 2 的冪次賦值,每個(gè)類(lèi)型占用一個(gè)二進(jìn)制中的位
const (
    O_RDONLY = 1 << iota // 1 (0b0001)
    O_WRONLY             // 2 (0b0010)
    O_CREAT              // 4 (0b0100)
)

// 文件操作配置類(lèi)
type Config struct {
    Flags int // 文件操作類(lèi)型標(biāo)識(shí)位
}

// 設(shè)置多個(gè)標(biāo)志
config.Flags = O_CREAT | O_WRONLY

// 清除標(biāo)識(shí)
config.Flags &^= O_CREAT  // 清除 O_CREAT 標(biāo)志

func Process(flags int) {
    // 檢查多個(gè)標(biāo)志
    if flags & (O_CREAT | O_WRONLY) != 0 {
        // 處理邏輯...
    }

    // ...    
}

2.2 工作原理

假設(shè) Flags = 3(二進(jìn)制 00000011),則 Flags & O_WRONLY 的結(jié)果如下:

   00000011 (Flags = 3)

& 00000010 (O_WRONLY = 2)

    -------------------------------------

    00000010 (結(jié)果 = 2)

結(jié)果不為 0, 即 Flags & O_WRONLY  != 0,說(shuō)明標(biāo)識(shí)位中含有 O_WRONLY

2.3 方案優(yōu)點(diǎn)

①高效存儲(chǔ):使用一個(gè)整數(shù)(如uint8, uint16, uint32等)的各個(gè)二進(jìn)制位來(lái)存儲(chǔ)多個(gè)布爾標(biāo)志,可以節(jié)省內(nèi)存。例如,一個(gè)32位整數(shù)可以存儲(chǔ)32個(gè)不同的標(biāo)志,而如果每個(gè)標(biāo)志都用一個(gè)bool變量(通常占1個(gè)字節(jié))存儲(chǔ),則需要32字節(jié)。

②快速組合和檢查:可以同時(shí)設(shè)置和檢查多個(gè)標(biāo)志。

// 同時(shí)設(shè)置多個(gè)標(biāo)志
config.Flags = O_CREAT | O_WRONLY

③性能高:位運(yùn)算CPU原生支持的操作,因此檢查標(biāo)志位的速度很快,比哈希表查找、字符串比較等快得多。

④便于參數(shù)傳遞:由于所有標(biāo)志都存儲(chǔ)在一個(gè)整數(shù)中,因此可以方便地作為函數(shù)參數(shù)傳遞、存儲(chǔ)在結(jié)構(gòu)體中或序列化到文件中。

三、實(shí)際案例

3.1 GO 源碼中文件操作配置的相關(guān)源碼

// 源碼位置:src/os/file.go

// Flags to OpenFile wrapping those of the underlying system. Not all
// flags may be implemented on a given system.
const (
	// Exactly one of O_RDONLY, O_WRONLY, or O_RDWR must be specified.
	O_RDONLY int = syscall.O_RDONLY // open the file read-only.
	O_WRONLY int = syscall.O_WRONLY // open the file write-only.
	O_RDWR   int = syscall.O_RDWR   // open the file read-write.
	// The remaining values may be or'ed in to control behavior.
	O_APPEND int = syscall.O_APPEND // append data to the file when writing.
	O_CREATE int = syscall.O_CREAT  // create a new file if none exists.
	O_EXCL   int = syscall.O_EXCL   // used with O_CREATE, file must not exist.
	O_SYNC   int = syscall.O_SYNC   // open for synchronous I/O.
	O_TRUNC  int = syscall.O_TRUNC  // truncate regular writable file when opened.
)

const (
	// Invented values to support what package os expects.
	O_RDONLY       = 0x00000
	O_WRONLY       = 0x00001
	O_RDWR         = 0x00002
	O_CREAT        = 0x00040
	O_EXCL         = 0x00080
	O_NOCTTY       = 0x00100
	O_TRUNC        = 0x00200
	O_NONBLOCK     = 0x00800
	O_APPEND       = 0x00400
	O_SYNC         = 0x01000
	O_ASYNC        = 0x02000
	O_CLOEXEC      = 0x80000
	o_DIRECTORY    = 0x100000   // used by internal/syscall/windows
	o_NOFOLLOW_ANY = 0x20000000 // used by internal/syscall/windows
	o_OPEN_REPARSE = 0x40000000 // used by internal/syscall/windows
)

// 源碼位置:src/syscall/syscall_windows.go
func Open(name string, flag int, perm uint32) (fd Handle, err error) {
	if len(name) == 0 {
		return InvalidHandle, ERROR_FILE_NOT_FOUND
	}
	namep, err := UTF16PtrFromString(name)
	if err != nil {
		return InvalidHandle, err
	}
	var access uint32
	switch flag & (O_RDONLY | O_WRONLY | O_RDWR) {
	case O_RDONLY:
		access = GENERIC_READ
	case O_WRONLY:
		access = GENERIC_WRITE
	case O_RDWR:
		access = GENERIC_READ | GENERIC_WRITE
	}
	if flag&O_CREAT != 0 {
		access |= GENERIC_WRITE
	}

    // ...

	return h, nil
}

3.2 goframe 框架中記錄日志內(nèi)容的配置項(xiàng)相關(guān)源碼

// 源碼位置:pkg/mod/github.com/gogf/gf@v1.16.9/os/glog/glog_logger.go

// 設(shè)置日志打印選項(xiàng)常量值
const (
	F_ASYNC      = 1 << iota // Print logging content asynchronously。
	F_FILE_LONG              // Print full file name and line number: /a/b/c/d.go:23.
	F_FILE_SHORT             // Print final file name element and line number: d.go:23. overrides F_FILE_LONG.
	F_TIME_DATE              // Print the date in the local time zone: 2009-01-23.
	F_TIME_TIME              // Print the time in the local time zone: 01:23:23.
	F_TIME_MILLI             // Print the time with milliseconds in the local time zone: 01:23:23.675.
	F_CALLER_FN              // Print Caller function name and package: main.main
	F_TIME_STD   = F_TIME_DATE | F_TIME_MILLI
)


// 源碼位置:pkg/mod/github.com/gogf/gf@v1.16.9/os/glog/glog_logger_config.go
// Config is the configuration object for logger.
type Config struct {
	Handlers             []Handler      `json:"-"`                    // Logger handlers which implement feature similar as middleware.
	Writer               io.Writer      `json:"-"`                    // Customized io.Writer.
    // 日志打印選項(xiàng)標(biāo)識(shí)位
	Flags                int            `json:"flags"`                // Extra flags for logging output features.
    // ...
}

func DefaultConfig() Config {
	c := Config{
		File:                defaultFileFormat,
		Flags:               F_TIME_STD,  // 打印內(nèi)容默認(rèn)設(shè)置為 標(biāo)準(zhǔn)時(shí)間格式
		Level:               LEVEL_ALL,
		CtxKeys:             []interface{}{gctx.CtxKey},
		// ...
	}
	
    // ...

	return c
}

// SetAsync enables/disables async logging output feature.
func (l *Logger) SetAsync(enabled bool) {
	if enabled {
		l.config.Flags = l.config.Flags | F_ASYNC   // 設(shè)置 F_ASYNC 標(biāo)識(shí)位
	} else {
		l.config.Flags = l.config.Flags & ^F_ASYNC  // 清除 F_ASYNC 標(biāo)識(shí)位
	}
}

// 源碼位置:pkg/mod/github.com/gogf/gf@v1.16.9/os/glog/glog_logger.go
// print prints `s` to defined writer, logging file or passed `std`.
func (l *Logger) print(ctx context.Context, level int, values ...interface{}) {
	// ...
	if l.config.HeaderPrint {
		// Time.
		timeFormat := ""
		if l.config.Flags&F_TIME_DATE > 0 {  // 判斷日志打印選項(xiàng)標(biāo)識(shí)位中是否含有 F_TIME_DATE
			timeFormat += "2006-01-02"
		}
		if l.config.Flags&F_TIME_TIME > 0 {
			if timeFormat != "" {
				timeFormat += " "
			}
			timeFormat += "15:04:05"
		}
		if l.config.Flags&F_TIME_MILLI > 0 {
			if timeFormat != "" {
				timeFormat += " "
			}
			timeFormat += "15:04:05.000"
		}

		// ...
	}

	// ...
}

3.3 Go 標(biāo)準(zhǔn)庫(kù)中的互斥鎖相關(guān)源碼

// 位于 src/sync/mutex.go
 
type Mutex struct {
	state int32     // 鎖狀態(tài)和一些標(biāo)志位
	sema  uint32    // 信號(hào)量,用于阻塞和喚醒等待的 goroutine
}
 
const (
	mutexLocked = 1 << iota // 是否被鎖定  
	mutexWoken              // 是否有協(xié)程被喚醒
	mutexStarving           // 是否處于饑餓模式
	mutexWaiterShift = iota // 表示等待鎖的阻塞協(xié)程個(gè)數(shù)
	starvationThresholdNs = 1e6
)

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • golang trace view視圖詳解

    golang trace view視圖詳解

    在golang中可以使用go pprof的工具對(duì)golang程序進(jìn)行性能分析,其中通過(guò)go trace 命令生成的trace view視圖對(duì)于我們分析系統(tǒng)延遲十分有幫助,鑒于當(dāng)前對(duì)trace view視圖的介紹還是很少,在粗略的看過(guò)trace統(tǒng)計(jì)原理后,將對(duì)這部分做比較詳細(xì)的介紹
    2023-08-08
  • 詳解go如何優(yōu)雅的使用接口與繼承

    詳解go如何優(yōu)雅的使用接口與繼承

    Go語(yǔ)言中的接口和嵌套結(jié)構(gòu)體是兩種重要的代碼設(shè)計(jì)方式,接口定義了一組方法簽名,使得不同的類(lèi)型能夠以相同的方式進(jìn)行交互,本文將給大家介紹go語(yǔ)言如何優(yōu)雅的使用接口與繼承,文中有詳細(xì)的代碼供大家參考,需要的朋友可以參考下
    2024-06-06
  • Golang http請(qǐng)求封裝的代碼示例

    Golang http請(qǐng)求封裝的代碼示例

    http請(qǐng)求封裝在項(xiàng)目中非常普遍,下面筆者封裝了http post請(qǐng)求傳json、form 和get請(qǐng)求,以備將來(lái)使用,文中代碼示例介紹的非常詳細(xì),需要的朋友可以參考下
    2023-06-06
  • Golang中Retry重試實(shí)踐

    Golang中Retry重試實(shí)踐

    本文主要介紹了Golang中Retry重試實(shí)踐,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2026-02-02
  • GoLang BoltDB數(shù)據(jù)庫(kù)詳解

    GoLang BoltDB數(shù)據(jù)庫(kù)詳解

    這篇文章主要介紹了GoLang BoltDB數(shù)據(jù)庫(kù),boltdb是使用Go語(yǔ)言編寫(xiě)的開(kāi)源的鍵值對(duì)數(shù)據(jù)庫(kù),boltdb存儲(chǔ)數(shù)據(jù)時(shí) key和value都要求是字節(jié)數(shù)據(jù),此處需要使用到 序列化和反序列化
    2023-02-02
  • go中的protobuf和grpc使用教程

    go中的protobuf和grpc使用教程

    gRPC 是 Google 公司基于 Protobuf 開(kāi)發(fā)的跨語(yǔ)言的開(kāi)源 RPC 框架,這篇文章主要介紹了go中的protobuf和grpc使用教程,需要的朋友可以參考下
    2024-08-08
  • golang使用RSA加密和解密的實(shí)現(xiàn)示例

    golang使用RSA加密和解密的實(shí)現(xiàn)示例

    在Golang中RSA加密和解密是一個(gè)常見(jiàn)的操作,本文主要介紹了golang使用RSA加密和解密的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的可以了解一下
    2025-03-03
  • 如何在golang中檢查文件是否存在

    如何在golang中檢查文件是否存在

    如果你用的是?Python,可通過(guò)?os.path.exists?這樣的標(biāo)準(zhǔn)庫(kù)函數(shù)實(shí)現(xiàn),遺憾的是,Go?標(biāo)準(zhǔn)庫(kù)沒(méi)有提供這樣直接的函數(shù),所以下面我們就來(lái)了解下如何使用GO語(yǔ)言能實(shí)現(xiàn)檢查文件是否存在呢
    2024-02-02
  • Go語(yǔ)言函數(shù)的延遲調(diào)用(Deferred Code)詳解

    Go語(yǔ)言函數(shù)的延遲調(diào)用(Deferred Code)詳解

    本文將介紹Go語(yǔ)言函數(shù)和方法中的延遲調(diào)用,正如名稱一樣,這部分定義不會(huì)立即執(zhí)行,一般會(huì)在函數(shù)返回前再被調(diào)用,我們通過(guò)一些示例來(lái)了解一下延遲調(diào)用的使用場(chǎng)景
    2022-07-07
  • Gin golang web開(kāi)發(fā)模型綁定實(shí)現(xiàn)過(guò)程解析

    Gin golang web開(kāi)發(fā)模型綁定實(shí)現(xiàn)過(guò)程解析

    這篇文章主要介紹了Gin golang web開(kāi)發(fā)模型綁定實(shí)現(xiàn)過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10

最新評(píng)論

定远县| 乐东| 大丰市| 吉隆县| 依安县| 湾仔区| 乳山市| 南丰县| 交口县| 耒阳市| 安康市| 三台县| 保德县| 宜章县| 涞水县| 德州市| 剑阁县| 怀安县| 濮阳县| 凤翔县| 离岛区| 来安县| 岱山县| 沂南县| 常山县| 兖州市| 博乐市| 合阳县| 得荣县| 东安县| 济阳县| 宁阳县| 松桃| 台湾省| 南华县| 日喀则市| 大方县| 德阳市| 长汀县| 金秀| 南丹县|