在 Vala 中继承接口 - 与基本方法不兼容

Inheriting interface in Vala - incompatible with base method

我正在尝试在 Vala 中实现 Gtk.StyleProvider。 "base class"(在 C 中)看起来像:

GtkIconFactory *        gtk_style_provider_get_icon_factory ()
GtkStyleProperties *    gtk_style_provider_get_style ()
gboolean                gtk_style_provider_get_style_property ()

在 VAPI 中:

[CCode (cheader_filename = "gtk/gtk.h")]
public interface StyleProvider {
    public abstract unowned Gtk.IconFactory get_icon_factory (Gtk.WidgetPath path);
    public abstract unowned Gtk.StyleProperties get_style (Gtk.WidgetPath path);
    public abstract bool get_style_property (Gtk.WidgetPath path, Gtk.StateFlags state, GLib.ParamSpec pspec, GLib.Value value);
}

根据 GtkStyleProvider.

的文档,前两种方法应该只 return NULL

因此,我写了一些 Vala 是这样的:

public class DerivedStyleProvider : Gtk.StyleProvider
{
    public Gtk.IconFactory? get_icon_factory (Gtk.WidgetPath path)
    {
        return null;
    }

    public Gtk.StyleProperties? get_style (Gtk.WidgetPath path)
    {
        return null;
    }

    bool get_style_property (Gtk.WidgetPath path,
                    Gtk.StateFlags state,
                    GLib.ParamSpec pspec,
                    out GLib.Value value)
    {
        return false; //TODO
    }
}

我对前两种方法有疑问。如果我在这里写了它们(带有 ?),那么我会收到以下错误:

error: overriding method `DerivedStyleProvider.get_icon_factory' is incompatible 
with base method `Gtk.StyleProvider.get_icon_factory': Base method expected 
return type `Gtk.IconFactory', but `Gtk.IconFactory?' was provided.
    public Gtk.IconFactory? get_icon_factory (Gtk.WidgetPath path)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

gtk_style_provider_get_style()方法相同

如果删除 ?,每个方法都会出现以下两个错误:

error: overriding method `DerivedsStyleProvider.get_icon_factory' 
is incompatible with base method `Gtk.StyleProvider.get_icon_factory': Base 
method expected return type `Gtk.IconFactory', but `Gtk.IconFactory' was provided.
        public Gtk.IconFactory get_icon_factory (Gtk.WidgetPath path)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/Preferences.vala:138.3-138.14: warning: `null' incompatible with 
return type `Gtk.IconFactory`
                return null;
                ^^^^^^^^^^^

第一个错误对我来说尤其有点奇怪,因为结果是 "error: expected TYPE, got TYPE"!

在前两种方法中添加unowned仍然会导致类似的错误。

我应该如何在 Vala 中实现 Gtk.StyleProvider 接口?

这在我的系统 (Vala 0.32.1) 上编译时没有错误或警告:

public class DerivedStyleProvider : GLib.Object, Gtk.StyleProvider
{
    public unowned Gtk.IconFactory get_icon_factory (Gtk.WidgetPath path)
    {
        // Evil cast to work around buggy declaration in VAPI file
        return (Gtk.IconFactory) null;
    }

    public Gtk.StyleProperties get_style (Gtk.WidgetPath path)
    {
        // Evil cast to work around buggy declaration in VAPI file
        return (Gtk.StyleProperties) null;
    }

    bool get_style_property (Gtk.WidgetPath path,
                    Gtk.StateFlags state,
                    GLib.ParamSpec pspec,
                    out GLib.Value value)
    {
        // I just assigned something here to make the compiler happy, you should make sure to use a correct value
        value = Value (typeof (string));
        return false; //TODO
    }
}

我做了这些更改:

  • 除界面外,还源自 GLib.Object
  • 在第一种方法上使用 unowned
  • 从 return 类型中删除可空值。
  • 将 null 转换为实际的 class 类型。 (这不是很漂亮,但问题出在 vapi 文件上。)
  • 为 out 参数分配一个虚拟值以使编译警告消失;)