• Что бы вступить в ряды "Принятый кодер" Вам нужно:
    Написать 10 полезных сообщений или тем и Получить 10 симпатий.
    Для того кто не хочет терять время,может пожертвовать средства для поддержки сервеса, и вступить в ряды VIP на месяц, дополнительная информация в лс.

  • Пользаватели которые будут спамить, уходят в бан без предупреждения. Спам сообщения определяется администрацией и модератором.

  • Гость, Что бы Вы хотели увидеть на нашем Форуме? Изложить свои идеи и пожелания по улучшению форума Вы можете поделиться с нами здесь. ----> Перейдите сюда
  • Все пользователи не прошедшие проверку электронной почты будут заблокированы. Все вопросы с разблокировкой обращайтесь по адресу электронной почте : info@guardianelinks.com . Не пришло сообщение о проверке или о сбросе также сообщите нам.

Go Interface Pitfalls: When nil != nil

Lomanu4 Оффлайн

Lomanu4

Команда форума
Администратор
Регистрация
1 Мар 2015
Сообщения
1,481
Баллы
155

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.



During the process of coding in Go, we may encounter a situation where, when using an interface type parameter (such as any or interface{}) to receive other parameters, the given parameter value is clearly nil, yet the inequality check x == nil does not hold. Why is this the case? This article will reveal the mystery.

Case Study


package main

import "fmt"

func main() {
var a any = nil
var b *int = nil
fmt.Println("isNil: ", isNil(a))
fmt.Println("isNil: ", isNil(b))
fmt.Println("b == nil: ", b == nil)
}

func isNil(x any) bool {
return x == nil
}

Program output:


isNil: true
isNil: false
b == nil: true

The Go code example above demonstrates some subtle differences when using the any type (i.e., interface{}) to determine whether a variable is nil. Specifically, it shows why, in some cases, a variable of type any is not considered nil even if its value is nil.

In this code sample, an isNil function is defined with a parameter x any. Then, in the main function, two variables a and b of different types are initialized, both assigned the value nil. Next, they are passed as arguments to the isNil function. Additionally, the result of b == nil is printed directly for comparison.

From the output, we can see that inside the isNil function, a == nil evaluates to true, while b == nil evaluates to false. However, outside the function, b == nil evaluates to true. This is because within the isNil function, the parameter is of type any, which causes x == nil to evaluate as false. To understand the specific reason, we need to look at the internal structure of any. Details below.

The Internal Structure of any (interface{})


In Go, any is an alias for interface{}. Internally, an interface{} value consists of two parts: the type part and the value part.

  • Type part: The concrete type held by the interface. If the interface holds a value of type *int, then the type part is *int.
  • Value part: The actual value held by the interface. If the value is the integer 3, then this part is 3; if it’s nil, then it’s nil.

When a value is assigned to an interface type (like any), the interface stores both the type and the actual value. Only when both the type part and the value part are nil is the interface considered to be nil.

Going back to the earlier code example, when the value of variable b is assigned to an interface variable x, the internal structure of x becomes type = *int and value = nil. Therefore, x == nil evaluates to false.

Checking for nil Using Reflection


Since == or != cannot always reliably determine whether an interface type is nil, how can we solve this problem? The answer is: by using reflection.

With reflection, we can directly check whether the value of a variable is nil.


func isNil(x any) bool {
if x == nil {
return true
}
value := reflect.ValueOf(x)
switch value.Kind() {
case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice, reflect.UnsafePointer:
return value.IsNil()
default:
return false
}
}
Summary


This article delves into why, when using Go, a variable of interface type may not be considered nil even when its value is nil. Through specific code examples and an analysis of the internal structure of any (i.e., interface{}), we uncover the essence of this phenomenon.

Key takeaways:

  • Interface type internal structure: An any (i.e., interface{}) is composed of a type part and a value part at the underlying level. An interface is considered nil only when both parts are nil.
  • Solution: Use reflection to accurately determine whether an interface-type variable is nil.

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.





Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

is the Next-Gen Serverless Platform for Web Hosting, Async Tasks, and Redis:

Multi-Language Support

  • Develop with Node.js, Python, Go, or Rust.

Deploy unlimited projects for free

  • pay only for usage — no requests, no charges.

Unbeatable Cost Efficiency

  • Pay-as-you-go with no idle charges.
  • Example: $25 supports 6.94M requests at a 60ms average response time.

Streamlined Developer Experience

  • Intuitive UI for effortless setup.
  • Fully automated CI/CD pipelines and GitOps integration.
  • Real-time metrics and logging for actionable insights.

Effortless Scalability and High Performance

  • Auto-scaling to handle high concurrency with ease.
  • Zero operational overhead — just focus on building.

Explore more in the

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

!


Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.



Follow us on X:

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.




Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.




Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

 
Вверх Снизу