Привет всем, меня зовут Мин.
В период самостоятельного изучения Golang я написал подробные учебные заметки и разместил их в своем личном общедоступном аккаунте WeChat «Время программирования на Go».Что касается языка Go, я тоже новичок, поэтому то, что я написал, должно больше подходить для новых студентов, если вы только изучаете язык Go, вам стоит обратить на него внимание, учиться и расти вместе.
Мой онлайн-блог:golang.iswbm.comМой Github: github.com/iswbm/GolangCodingTime
1. Что такое пустой интерфейс?
Пустой интерфейс — это особая форма типа интерфейса.Обычные интерфейсы имеют методы, но пустые интерфейсы не определяют никаких портов методов.Поэтому можно сказать, что все типы реализуют как минимум пустые интерфейсы.
type empty_iface interface {
}
Каждый интерфейс содержит два свойства: одно — значение, а другое — тип.
Для пустых интерфейсов оба равны нулю, вы можете использовать fmt для проверки
package main
import (
"fmt"
)
func main() {
var i interface{}
fmt.Printf("type: %T, value: %v", i, i)
}
Вывод выглядит следующим образом
type: <nil>, value: <nil>
2. Как использовать пустой интерфейс?
Первый, обычно мы будем напрямую использоватьinterface{}
Экземпляр объявлен как тип, и этот экземпляр может содержать значения любого типа.
package main
import (
"fmt"
)
func main() {
// 声明一个空接口实例
var i interface{}
// 存 int 没有问题
i = 1
fmt.Println(i)
// 存字符串也没有问题
i = "hello"
fmt.Println(i)
// 存布尔值也没有问题
i = false
fmt.Println(i)
}
второй, если вы хотите, чтобы ваша функция получала значение любого типа, вы также можете использовать пустой интерфейс
Получает значение любого типа Пример
package main
import (
"fmt"
)
func myfunc(iface interface{}){
fmt.Println(iface)
}
func main() {
a := 10
b := "hello"
c := true
myfunc(a)
myfunc(b)
myfunc(c)
}
Получить любое количество значений любого типа Пример
package main
import (
"fmt"
)
func myfunc(ifaces ...interface{}){
for _,iface := range ifaces{
fmt.Println(iface)
}
}
func main() {
a := 10
b := "hello"
c := true
myfunc(a, b, c)
}
третий, вы также определяете массив, слайс, карту, strcut, которые могут принимать любой тип, например, здесь определите слайс
package main
import "fmt"
func main() {
any := make([]interface{}, 5)
any[0] = 11
any[1] = "hello world"
any[2] = []int{11, 22, 33, 44}
for _, value := range any {
fmt.Println(value)
}
}
3. Несколько ям, на которые стоит обратить внимание в пустом интерфейсе
яма 1: Пустой интерфейс может содержать любое значение, но это не означает, что любой тип может содержать значение пустого типа интерфейса.
С точки зрения реализации значение любого типа удовлетворяет пустому интерфейсу. Следовательно, пустой тип интерфейса может содержать любое значение, а также может принимать исходное значение из пустого интерфейса.
Но если вы присвоите объект пустого типа интерфейса объекту фиксированного типа (например, int, string и т. д.), будет сообщено об ошибке.
package main
func main() {
// 声明a变量, 类型int, 初始值为1
var a int = 1
// 声明i变量, 类型为interface{}, 初始值为a, 此时i的值变为1
var i interface{} = a
// 声明b变量, 尝试赋值i
var b int = i
}
Эта ошибка как то, что можно положить в подарочную коробку, это точно можно положить в контейнер, но и наоборот, вещи, которые можно положить в контейнер, нельзя положить в подарочную коробку, это прямо запрещено в Go. Обратная операция. (утверждение: Должны быть другие причины лежащего в основе принципа, но новичкам это объяснение может быть легче понять. )
.\main.go:11:6: cannot use i (type interface {}) as type int in assignment: need type assertion
Яма 2:: После того, как пустой интерфейс содержит массивы и слайсы, объект больше не может быть слайсирован.
package main
import "fmt"
func main() {
sli := []int{2, 3, 5, 7, 11, 13}
var i interface{}
i = sli
g := i[1:3]
fmt.Println(g)
}
Выполнение сообщит об ошибке.
.\main.go:11:8: cannot slice i (type interface {})
яма 3: когда вы используете пустой интерфейс для получения параметров любого типа, его статический тип — interface{}, но мы не знаем динамический тип (это int, string или что-то еще), поэтому вам нужно использовать утверждение типа .
package main
import (
"fmt"
)
func myfunc(i interface{}) {
switch i.(type) {
case int:
fmt.Println("参数的类型是 int")
case string:
fmt.Println("参数的类型是 string")
}
}
func main() {
a := 10
b := "hello"
myfunc(a)
myfunc(b)
}
Вывод выглядит следующим образом
参数的类型是 int
参数的类型是 string