【问题标题】:Language where variable types are themselves variables?变量类型本身就是变量的语言?
【发布时间】:2016-08-02 18:13:01
【问题描述】:

我将使用 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 中是否可能(一些我想不到的预处理器魔法)?我假设没有,但是有没有可以将类型本身用作变量的语言?我很想探索以类型为中心的编程的含义

编辑:正如 itsme86 所指出的,C# 具有 Type 类的这种能力。 C++ 概念和 Haskell 类型类也很有趣。

【问题讨论】:

  • 我不认为我遵循您的要求。你想让return obj->x;返回int吗?
  • 是的。但是,根据类型运算符,obj->x 可能位于 obj 的地址,也可能是 1 个字节的偏移量(给定结构设置)。我想要的是一个可以用来识别类型而不是值的变量
  • 您要查找的功能是type introspection。它在一些面向对象的语言中可用,但在 C 中不可用(尽管您可以通过添加 type 成员作为所有结构的第一个成员来破解它)。
  • @user3386109 这部分是我想要的,但是变量可以用任何语言保存这些值吗?例如,C++ 支持 dynamic_cast,但它看起来不允许我创建一个值为类型的新变量
  • C# 绝对有这个能力。有一个Type 类,它包含关于它所指的任何类型的各种信息。还可以根据该信息在运行时创建该类型的新对象。

标签: c programming-languages


【解决方案1】:

如果你把类型安全抛在脑后,你可以使用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));

但我不会真的推荐它。

【讨论】:

  • 这绝对是一种获得我一直在寻找的有趣结果的方法。但是,我问的主要原因是因为我想看看变量类型是否可以包含类型作为它们的值,即“type t = int”。这可以用任何语言实现吗?
【解决方案2】:

在 Java 中,您可以通过反射 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&lt;T&gt; 的对象,它提供对MyClass 类信息的访问。这个对象也可以通过类的任何实例来检索,参见myInstance.getClass()。我包括了几个例子来展示什么是可访问的。您还可以通过其Class 对象创建一个类的新实例。有关更多信息,您可能还想查看 java.lang.reflect 包的 Javadoc。


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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-13
    • 2012-06-30
    • 2021-03-26
    • 1970-01-01
    相关资源
    最近更新 更多