英文:
How do programs know the types at runtimes of primitives statically typed languages
问题
Go和Scala都提供了在运行时检查类型的方法:
Scala:
class A
class B extends A
val a: A = new A // 静态类型: A 动态类型: A
val ab: A = new B // 静态类型: A 动态类型: B
val b: B = new B // 静态类型: B 动态类型: B
def thing(x: Any): String = x match {
case t: Int => "Int"
case t: A => "A"
case t: B => "B"
case t: String => "String"
case _ => "unknown type"
}
Go:
package main
import (
"fmt"
"reflect"
)
type A struct {
field1 int
field2 string
}
func printTypeOf(t interface{}) {
fmt.Println(reflect.TypeOf(t))
}
func main() {
i := 234234 // int
s := "hello world" // string
p := &A{3234234, "stuff"} // *A
fmt.Print("The type of i is: ")
printTypeOf(i)
fmt.Print("The type of s is: ")
printTypeOf(s)
fmt.Print("The type of p is: ") // pass a pointer
printTypeOf(p)
fmt.Print("The type of the reference of p is: ") // pass a value
printTypeOf(*p)
}
这些代码是如何在内部工作的?我猜对于结构体和类,对象的类型存储在一个隐藏字段中(所以在golang中的结构实际上是struct { field1 int field2 string type type }
)。但是,函数如何得到11010110并知道它是指向内存地址214的指针、整数214还是字符Ö?所有的值是否都以表示其类型的字节进行传递?
英文:
Both Go and Scala provide ways of checking types at runtime:
Scala:
class A
class B extends A
val a: A = new A // static type: A dynamic type: A
val ab: A = new B // static type: A dynamic type: B
val b: B = new B // static type: B dynamic type: B
def thing(x: Any): String = x match {
case t: Int => "Int"
case t: A => "A"
case t: B => "B"
case t: String => "String"
case _ => "unknown type"
}
Go:
package main
import (
"fmt"
"reflect"
)
struct A {
field1 int
field2 string
}
func printTypeOf(t interface{}) {
fmt.Println(reflect.TypeOf(t))
}
func main() {
i := 234234 // int
s := "hello world" // string
p := &A{3234234, "stuff"} // *A
fmt.Print("The type of i is: ")
printTypeOf(i)
fmt.Print("The type of s is: ")
printTypeOf(s)
fmt.Print("The type of p is: ") // pass a pointer
printTypeOf(p)
fmt.Print("The type of the reference of p is: ") // pass a value
printTypeOf(*p)
}
How exactly does this work internally? I presume for structs and classes, the type of the object is stored in a hidden field (so the structure in golang is really struct { field1 int field2 string type type }. But how on earth can function be given 11010110 and know whether it's a pointer to memory address at 214, the integer 214 or the character Ö? Are all values secretly passed with a byte which represents its type?
答案1
得分: 2
在Scala中,每个对象都有一个指向其类的指针。当你使用原始参数(Int
,Char
等)调用thing
时,它会自动装箱为一个对象(java.lang.Integer
,java.lang.Character
等)。你代码中对Int
的匹配实际上被转换为对Integer
的匹配。
在Go中,类型不存储在结构体中,而是存储在接口值中:
接口值表示为一个两个字的对,其中一个指向存储在接口中的类型信息的指针,另一个指向关联数据的指针。将b分配给类型为Stringer的接口值会设置接口值的两个字。
因此,当你调用printTypeOf(whatever)
时,whatever
会被转换为interface{}
,并且它的类型会与whatever
本身一起存储在这个新值中。
英文:
In Scala, each object has a pointer to its class. When you call thing
with a primitive argument (Int
, Char
, etc.), it's automatically boxed to an object (java.lang.Integer
, java.lang.Character
, etc.). The match against Int
in your code is actually translated to a match against Integer
.
In Go, the type isn't stored in structs, but in interface values:
So when you call printTypeOf(whatever)
, whatever
is converted to interface {}
and its type is stored in this new value along with whatever
itself.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论