Go中一些工具函数封装
2022年3月13日
类型转换
string
和[]byte
。利用指针直接构造的方式,可以避免拷贝开销,对大字符串有很好的效果。
// 小于1.20
func String2Bytes(s string) []byte {
bs := struct {
string
Cap int
}{s, len(s)}
return *(*[]byte)(unsafe.Pointer(&bs))
}
func Bytes2String(bs []byte) string {
return *(*string)(unsafe.Pointer(&bs))
}
// 1.20
func String2Bytes(s string) []byte {
return unsafe.Slice(unsafe.StringData(s), len(s))
}
func Bytes2String(bs []byte) string {
return unsafe.String(&bs[0], len(bs))
}
string
和float
func Float2String(f float64) string {
return strconv.FormatFloat(f, 'f', -1, 64)
}
func String2Float(s string) float64 {
f, err := strconv.ParseFloat(s, 64)
if err != nil {
fmt.Println(err)
}
return f
}
- IPV4地址转
int
,IPV4其实本来就是4字节长度,便于查看才有点分十进制的展示形式,为了节省空间,数据库存储最后还是使用int
func Ip2Int(ip string) int {
i := big.NewInt(0).SetBytes(net.ParseIP(ip).To4()).Int64()
return int(i)
}
func Int2Ip(ip int) string {
return net.IPv4(byte(ip>>24), byte(ip>>16), byte(ip>>8), byte(ip)).String()
}
随机数
// 预定义字符集
const (
Number = "0123456789"
LowerLetter = "abcdefghijklmnopqrstuvwxyz"
UpperLetter = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
)
// 随机种子。这种方式为在初始化时固定随机种子
func init() {
rand.Seed(time.Now().UnixNano())
}
// 随机数
func RandInt(max int) int {
return rand.Intn(max)
}
// 随机字符串:数字+大写字母
func RandString(length int) string {
return RandStringWithCharset(length, Number+UpperLetter)
}
// 随机字符串:用户自定义字符集
func RandStringWithCharset(length int, letter string) string {
b := make([]byte, length)
r := rand.New(rand.NewSource(time.Now().UnixNano()))
n := len(letter)
for i := range b {
b[i] = letter[r.Intn(n)]
}
return *(*string)(unsafe.Pointer(&b))
}
时间
// go1.20新增以下三个常量
const (
DateTime = "2006-01-02 15:04:05"
DateOnly = "2006-01-02"
TimeOnly = "15:04:05"
)
func Now() string {
return time.Now().Format(DateTime)
}
func DayStart(add int) time.Time {
y, m, d := time.Now().Date()
return time.Date(y, m, d+add, 0, 0, 0, 0, time.Local)
}
func DayEnd(add int) time.Time {
y, m, d := time.Now().Date()
return time.Date(y, m, d+add, 23, 59, 59, 0, time.Local)
}
func MonthStart(add int) time.Time {
y, m, _ := time.Now().Date()
return time.Date(y, m+time.Month(add), 1, 0, 0, 0, 0, time.Local)
}
func MonthEnd(add int) time.Time {
y, m, _ := time.Now().Date()
return time.Date(y, m+time.Month(add)+1, 1, 0, 0, 0, 0, time.Local).Add(-1 * time.Second)
}
文件
// 判断文件是否存在
func IsFileExist(name string) bool {
_, err := os.Stat(name)
return err == nil || !os.IsNotExist(err)
}
// 打开文件追加写。(自动创建目录和文件)
func OpenFile(name string) (*os.File, error) {
if !IsFileExist(name) {
dir := filepath.Dir(name)
if !IsFileExist(dir) {
err := os.MkdirAll(dir, os.ModePerm)
if err != nil {
return nil, err
}
}
}
f, err := os.OpenFile(name, os.O_RDWR|os.O_APPEND|os.O_CREATE, os.ModePerm)
return f, err
}