This is the 7th day of my participation in Gwen Challenge

At the bottom, interfaces implement two elements, type T and value V, where V is a real value, such as int, struct, point, or even the interface itself. For example, if we store the value of int 3 in an interface, the interface result is roughly (T=int, V=3). V is also known as the dynamic value of the interface, because during the execution of the program, the interface V may be different values.

An interface that is nil means that its T and V are not set (T=nil, V is not set). To put it another way, a nil interface, its type T must be nil. If we store a null pointer *int into an interface value (V), the interface type will be *int (T= *int,V=nil), as in the example below.

This can be confusing, especially if a nil value is stored in an interface’s V, such as error

func returnsError(a) error {
	var p *MyError = nil // Create a variable p whose type is *myError value is nil
	if bad() {
		p = ErrBad
	}
	return p // Will always return a non-nil error.
}
Copy the code

If the program ends up running properly, this function returns p nil, p is the error interface, and inside this interface is (T=*MyError,V=nil). And as a result, if you compare p to nil externally, it’s always going to be an error, even if there’s nothing really going on in your program. To return a proper nil error, methods must return an explicit nil value to indicate that no exception occurred:

func returnsError(a) error {
	if bad() {
		return ErrBad
	}
	return nil
}
Copy the code

A good rule of thumb is to always sign a function with an error type (as we did above) rather than a specific type, such as *myError, to ensure that error is created correctly (PS: Just create a new error on return, such as return error.new(), instead of creating a new error outside, so as in the top example, you might set it to nil and think it’s nil, when its type isn’t empty.) For example, the os.open() method returns * os.patherror. (PS: I’ll post how it’s used)

func openFileNolog(name string, flag int, perm FileMode) (*File, error) {
	if name == "" {
		return nil, &PathError{"open", name, syscall.ENOENT} // Return error directly
	}
	r, errf := openFile(name, flag, perm)
	if errf == nil {
		return r, nil
	}
	r, errd := openDir(name)
	if errd == nil {
		ifflag&O_WRONLY ! =0|| flag&O_RDWR ! =0 {
			r.Close()
			return nil, &PathError{"open", name, syscall.EISDIR}
		}
		return r, nil
	}
	return nil, &PathError{"open", name, errf}
}
Copy the code

Remember, as long as any specific value is stored in an interface, that interface is not nil. More details can be found at blog.golang.org/laws-of-ref…

A. concrete B. schematically C. schematically D. schematicallyCopy the code