变量类型本身就是变量的语言?

时间:2016-08-02 18:13:01

标签: c programming-languages

我将使用C作为示例语言来表明我的意思。

struct parent
{
    int x;
    char y;
};
struct child
{
    char y;
    int x;
};

int foo(void * s, type obj_type)
{
    // the casting is done using a "type" variable
    obj_type obj = (obj_type) s;
    return obj->x;
}

int main(int argc, char** argv)
{
    type obj_type = struct parent *;
    struct parent p;
    p.x = 0;

    //returns 0
    foo(&p, obj_type);

    obj_type = struct child *;
    struct child c;
    c.x = 5;

    // returns 5
    foo(&c, obj_type);

    return 0;
}

正如您所看到的,x被放置在两个结构的内存中的不同位置,所以我不能在内存中有一个静态偏移量。无论如何这在C中是否可能(一些我无法想到的预处理器魔法)?我假设没有,但有哪些语言类型本身可以用作变量?我很想探索以类型为中心的编程的含义

编辑:正如它的80指出的那样,C#具有Type类的这种能力。此外,C ++ Concepts和Haskell Type类也很有用。

2 个答案:

答案 0 :(得分:2)

如果您保留了类型安全性,则可以使用offsetof(来自stddef.h):

int foo(unsigned char * s, size_t offset)
{
    int* ptr = (int*)(s + offset);
    return *ptr;
}

foo((unsigned char*)&p, offsetof(struct parent, x));

但我不会真的推荐它。

答案 1 :(得分:0)

在Java中,您可以通过Reflections API访问类型信息。这是一个例子:

package stackoverflow;

import java.util.Arrays;

public class MyClass {
    public static void main(String[] args) {
        MyClass myInstance = new MyClass(42, "foo");
        Class<MyClass> myClass = MyClass.class;
        System.out.println(myInstance instanceof MyClass);
        System.out.println(myInstance.getClass().equals(myClass));
        System.out.println(myClass.getName());
        System.out.println(Arrays.toString(myClass.getDeclaredFields()));
        System.out.println(Arrays.toString(myClass.getDeclaredMethods()));
    }

    private final int i;
    private final String s;

    public MyClass(int i, String s) {
        this.i = i;
        this.s = s;
    }

    public int getI() {
        return i;
    }

    public String getS() {
        return s;
    }
}

输出:

true
true
stackoverflow.MyClass
[private final int stackoverflow.MyClass.i, private final java.lang.String stackoverflow.MyClass.s]
[public int stackoverflow.MyClass.getI(), public java.lang.String stackoverflow.MyClass.getS(), public static void stackoverflow.MyClass.main(java.lang.String[])]

如您所见,MyClass.class是泛型java.lang.Class<T>的对象,可以访问有关类MyClass的信息。也可以通过类的任何实例检索此对象,请参阅myInstance.getClass()。我提供了一些示例来说明可访问的内容。您还可以通过其Class对象创建类的新实例。有关更多信息,您可能还需要查看java.lang.reflect包的Javadoc。

请注意,这只允许您访问这些信息。例如,它不允许您更改现有实例的类型,我认为这是一件好事。但是,这在Python中似乎是可能的:

Can I dynamically convert an instance of one class to another?