我是Golang的新手,希望为物理设备建模,以测量光强度,质量,电流等数量。因此,作为一个起点,我将定义一个设备结构如下:
const (
// Light can be measured in the form of luminosity
Light = 1<< iota
Mass
ElectricalCurrent
)
type PhysicalDevice struct{
Owner string
ID string
Description string
}
我现在很困惑如何表达设备的功能(它可以测量什么)和测量单位。例如,我想表达一个物理设备可以测量安培的电流。但是,我还想表达一下,PhysicalDevice可以测量多个数量。例如,它可以测量电流和温度。
PhysicalDevice的功能事先不知道,可以包含任意组合的功能。
我正在考虑使用与C ++ bitset相当的东西来表示设备可以测量的物理量(这首先是正确的方法吗?)。
我没有找到Go bitset类型,也不确定如何表达。我还需要将测量的物理量映射到相应的单位。
你应该明白,试图在Go中复制另一种语言的功能通常被认为是一个坏主意。有一种“去”的做事方式。
你可能想要考虑iota
和像this example on the Go playground这样的位掩码操作。我也在这里包含了代码(在所有剽窃的荣耀中):
package main
import "fmt"
func main() {
TestAddFlag()
TestHasFlag()
TestClearFlag()
TestToggleFlag()
fmt.Println("all tests passed")
}
type Bitmask uint32
func (f Bitmask) HasFlag(flag Bitmask) bool { return f&flag != 0 }
func (f *Bitmask) AddFlag(flag Bitmask) { *f |= flag }
func (f *Bitmask) ClearFlag(flag Bitmask) { *f &= ^flag }
func (f *Bitmask) ToggleFlag(flag Bitmask) { *f ^= flag }
const (
TESTFLAG_ONE Bitmask = 1 << iota
TESTFLAG_TWO
TESTFLAG_THREE
)
func TestAddFlag() {
var mainFlag Bitmask = TESTFLAG_TWO
mainFlag.AddFlag(TESTFLAG_THREE)
if mainFlag&(1<<TESTFLAG_THREE) != 0 {
panic("failed")
}
}
func TestClearFlag() {
var mainFlag Bitmask = TESTFLAG_ONE | TESTFLAG_THREE
mainFlag.ClearFlag(TESTFLAG_THREE)
if mainFlag&(1<<TESTFLAG_ONE) != 0 {
panic("failed")
}
}
func TestHasFlag() {
var mainFlag Bitmask = TESTFLAG_ONE | TESTFLAG_THREE
if !mainFlag.HasFlag(TESTFLAG_THREE) {
panic("failed")
}
}
func TestToggleFlag() {
flag := TESTFLAG_ONE | TESTFLAG_THREE
flag.ToggleFlag(TESTFLAG_ONE)
if flag.HasFlag(TESTFLAG_ONE) {
panic("failed")
}
flag.ToggleFlag(TESTFLAG_ONE)
if !flag.HasFlag(TESTFLAG_ONE) {
panic("failed")
}
}
使用= 1 << iota
定义功能:
const (
Light Capability = 1 << iota
Mass
ElectricalCurrent
Energy
)
请注意,表达式仅在第一个常量上需要。相同的表达式(但具有更新的iota
值)将用于同一组中的连续行。
这是一个完整的工作示例:
package main
import (
"fmt"
"strings"
)
type Capability int
const (
// Light can be measured in the form of luminosity
Light Capability = 1 << iota
Mass
ElectricalCurrent
Energy
)
func (c Capability) String() string {
var caps []string
if c&Light > 0 {
caps = append(caps, "Light")
}
if c&Mass > 0 {
caps = append(caps, "Mass")
}
if c&ElectricalCurrent > 0 {
caps = append(caps, "ElectricalCurrent")
}
if c&Energy > 0 {
caps = append(caps, "Energy")
}
return strings.Join(caps, "|")
}
type PhysicalDevice struct {
Owner string
ID string
Description string
Capability Capability
}
func (pd PhysicalDevice) String() string {
return "Owner: " + pd.Owner + "\n" +
"ID: " + pd.ID + "\n" +
"Description: " + pd.Description + "\n" +
"Capability: " + pd.Capability.String() + "\n"
}
func main() {
dev := PhysicalDevice{
Owner: "Albert Einstein",
ID: "E=mc^2",
Description: "My well-known formula as a device",
Capability: Energy | Mass | Light,
}
fmt.Println(dev)
}
代码可以在The Go Playground上找到。