-
作为事件信号或标志:在并发编程中,可以使用空结构体来表示某个事件的发生或作为一个简单的同步信号。
-
仅关注方法而不存储数据:如果一个类型主要定义了方法,而不需要存储任何实际的数据,那么可以使用空结构体。
-
节省内存:当只需要标识某个元素的存在,而不需要存储任何相关数据时,使用空结构体可以节省内存空间,因为空结构体不占用内存。
-
集合元素唯一性:在某些集合(如
map
)中,如果键只需要保证唯一性,而不需要存储值,可以使用空结构体作为值。
以下是针对上述提到的空结构体使用场景的代码示例:
- 作为事件信号或标志(在并发编程中):
package main
import (
"fmt"
"sync"
"time"
)
// 定义一个全局的事件通道
var eventChan = make(chan struct{})
func worker(wg *sync.WaitGroup) {
defer wg.Done()
// 模拟工作
time.Sleep(2 * time.Second)
// 发送事件信号
eventChan <- struct{}{}
}
func main() {
var wg sync.WaitGroup
wg.Add(1)
go worker(&wg)
// 等待事件信号
<-eventChan
fmt.Println("收到事件信号")
wg.Wait()
}
2.仅关注方法而不存储数据:
package main
import "fmt"
type Logger struct{}
func (l Logger) Log(message string) {
fmt.Println(message)
}
func main() {
logger := Logger{}
logger.Log("这是一条日志")
}
3.节省内存(当只需要标识某个元素的存在)
package main
import "fmt"
// 假设我们有一个用户在线状态的映射
var onlineUsers = make(map[string]struct{})
func markUserOnline(username string) {
onlineUsers[username] = struct{}{}
}
func isUserOnline(username string) bool {
_, exists := onlineUsers[username]
return exists
}
func main() {
markUserOnline("user1")
fmt.Println(isUserOnline("user1"))
fmt.Println(isUserOnline("user2"))
}
4.集合元素唯一性(在 map
中):
package main
import "fmt"
func main() {
// 用空结构体作为值,表示只关心键的唯一性
uniqueKeys := make(map[string]struct{})
uniqueKeys["key1"] = struct{}{}
uniqueKeys["key2"] = struct{}{}
// 检查键是否存在
if _, exists := uniqueKeys["key1"]; exists {
fmt.Println("Key1 exists")
}
}