golang staticcheck

staticcheck.io

下面是摘抄出来的几个:

SA6001 – Missing an optimization opportunity when indexing maps by byte slices

Map keys must be comparable, which precludes the use of byte slices. This usually leads to using string keys and converting byte slices to strings.

Normally, a conversion of a byte slice to a string needs to copy the data and causes allocations. The compiler, however, recognizes m[string(b)] and uses the data of b directly, without copying it, because it knows that the data can’t change during the map lookup. This leads to the counter-intuitive situation that

k := string(b)
println(m[k])
println(m[k])
will be less efficient than

println(m[string(b)])
println(m[string(b)])
because the first version needs to copy and allocate, while the second one does not.

For some history on this optimization, check out commit f5f5a8b6209f84961687d993b93ea0d397f5d5bf in the Go repository.

Available since
2017.1

SA6005 – Inefficient string comparison with strings.ToLower or strings.ToUpper

Converting two strings to the same case and comparing them like so

if strings.ToLower(s1) == strings.ToLower(s2) {

}
is significantly more expensive than comparing them with strings.EqualFold(s1, s2). This is due to memory usage as well as computational complexity.

strings.ToLower will have to allocate memory for the new strings, as well as convert both strings fully, even if they differ on the very first byte. strings.EqualFold, on the other hand, compares the strings one character at a time. It doesn’t need to create two intermediate strings and can return as soon as the first non-matching character has been found.

For a more in-depth explanation of this issue, see https://blog.digitalocean.com/how-to-efficiently-compare-strings-in-go/

Available since
2019.2

SA9003 – Empty body in an if or else branch
Available since
2017.1

S1000 – Use plain channel send or receive instead of single-case select

Select statements with a single case can be replaced with a simple send or receive.

Before:

select {
case x := <-ch:
fmt.Println(x)
}
After:

x := <-ch
fmt.Println(x)
Available since
2017.1

S1003 – Replace call to strings.Index with strings.Contains

Before:

if strings.Index(x, y) != -1 {}
After:

if strings.Contains(x, y) {}
Available since
2017.1

S1004 – Replace call to bytes.Compare with bytes.Equal

Before:

if bytes.Compare(x, y) == 0 {}
After:

if bytes.Equal(x, y) {}
Available since
2017.1

S1005 – Drop unnecessary use of the blank identifier
In many cases, assigning to the blank identifier is unnecessary.

Before:

for _ = range s {}
x, _ = someMap[key]
_ = <-ch
After:

for range s{}
x = someMap[key]
<-ch
Available since
2017.1

S1007 – Simplify regular expression by using raw string literal

Raw string literals use instead of " and do not support any escape sequences. This means that the backslash (`) can be used freely, without the need of escaping.

Since regular expressions have their own escape sequences, raw strings can improve their readability.

Before:

regexp.Compile("\A(\w+) profile: total \d+\n\z")
After:

regexp.Compile(\A(\w+) profile: total \d+\n\z)
Available since
2017.1

S1009 – Omit redundant nil check on slices

The len function is defined for all slices, even nil ones, which have a length of zero. It is not necessary to check if a slice is not nil before checking that its length is not zero.

Before:

if x != nil && len(x) != 0 {}
After:

if len(x) != 0 {}
Available since
2017.1

S1012 – Replace time.Now().Sub(x) with time.Since(x)

The time.Since helper has the same effect as using time.Now().Sub(x) but is easier to read.

Before:

time.Now().Sub(x)
After:

time.Since(x)
Available since
2017.1

S1016 – Use a type conversion instead of manually copying struct fields

Two struct types with identical fields can be converted between each other. In older versions of Go, the fields had to have identical struct tags. Since Go 1.8, however, struct tags are ignored during conversions. It is thus not necessary to manually copy every field individually.

Before:

var x T1
y := T2{
Field1: x.Field1,
Field2: x.Field2,
}
After:

var x T1
y := T2(x)
Available since
2017.1

S1017 – Replace manual trimming with strings.TrimPrefix

Instead of using strings.HasPrefix and manual slicing, use the strings.TrimPrefix function. If the string doesn’t start with the prefix, the original string will be returned. Using strings.TrimPrefix reduces complexity, and avoids common bugs, such as off-by-one mistakes.

Before:

if strings.HasPrefix(str, prefix) {
str = str[len(prefix):]
}
After:

str = strings.TrimPrefix(str, prefix)
Available since
2017.1

S1018 – Use copy for sliding elements

copy() permits using the same source and destination slice, even with overlapping ranges. This makes it ideal for sliding elements in a slice.

Before:

for i := 0; i < n; i++ {
bs[i] = bs[offset+i]
}
After:

copy(bs[:n], bs[offset:])
Available since
2017.1

S1024 – Replace x.Sub(time.Now()) with time.Until(x)

The time.Until helper has the same effect as using x.Sub(time.Now()) but is easier to read.

Before:

x.Sub(time.Now())
After:

time.Until(x)
Available since
2017.1

S1030 – Use bytes.Buffer.String or bytes.Buffer.Bytes

bytes.Buffer has both a String and a Bytes method. It is almost never necessary to use string(buf.Bytes()) or []byte(buf.String()) – simply use the other method.

The only exception to this are map lookups. Due to a compiler optimization, m[string(buf.Bytes())] is more efficient than m[buf.String()].

Available since
2017.1

S1032 – Use sort.Ints(x), sort.Float64s(x), and sort.Strings(x)

The sort.Ints, sort.Float64s and sort.Strings functions are easier to read than sort.Sort(sort.IntSlice(x)), sort.Sort(sort.Float64Slice(x)) and sort.Sort(sort.StringSlice(x)).

Before:

sort.Sort(sort.StringSlice(x))
After:

sort.Strings(x)
Available since
2019.1

S1033 – Unnecessary guard around call to delete

Calling delete on a nil map is a no-op.

Available since
2019.2

ST1008 – A function’s error value should be its last return value

A function’s error value should be its last return value.

Available since
2019.1

ST1017 – Don’t use Yoda conditions

Yoda conditions are conditions of the kind if 42 == x, where the literal is on the left side of the comparison. These are a common idiom in languages in which assignment is an expression, to avoid bugs of the kind if (x = 42). In Go, which doesn’t allow for this kind of bug, we prefer the more idiomatic if x == 42.

Available since
2019.2

ST1020 – The documentation of an exported function should start with the function’s name

non-default

Doc comments work best as complete sentences, which allow a wide variety of automated presentations. The first sentence should be a one-sentence summary that starts with the name being declared.

If every doc comment begins with the name of the item it describes, you can use the doc subcommand of the go tool and run the output through grep.

See https://golang.org/doc/effective_go.html#commentary for more information on how to write good documentation.

Available since
2020.1

ST1021 – The documentation of an exported type should start with type’s name

non-default

Doc comments work best as complete sentences, which allow a wide variety of automated presentations. The first sentence should be a one-sentence summary that starts with the name being declared.

If every doc comment begins with the name of the item it describes, you can use the doc subcommand of the go tool and run the output through grep.

See https://golang.org/doc/effective_go.html#commentary for more information on how to write good documentation.

Available since
2020.1

ST1022 – The documentation of an exported variable or constant should start with variable’s name

non-default

Doc comments work best as complete sentences, which allow a wide variety of automated presentations. The first sentence should be a one-sentence summary that starts with the name being declared.

If every doc comment begins with the name of the item it describes, you can use the doc subcommand of the go tool and run the output through grep.

See https://golang.org/doc/effective_go.html#commentary for more information on how to write good documentation.

Available since
2020.1

QF1009 – Use time.Time.Equal instead of == operator
Available since
2021.1

QF1010 – Convert slice of bytes to string when printing it
Available since
2021.1

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值