【问题标题】:Inheriting interface in Vala - incompatible with base method在 Vala 中继承接口 - 与基方法不兼容
【发布时间】:2017-05-06 22:37:17
【问题描述】:

我正在尝试在 Vala 中实现 Gtk.StyleProvider。 “基类”(在 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 的文档,前两种方法只应返回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;
                ^^^^^^^^^^^

特别是第一个错误对我来说有点奇怪,因为结果是“错误:预期的 TYPE,得到了 TYPE”!

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

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

【问题讨论】:

  • 您必须将方法指定为public override Gtk...(注意 override 关键字)。此外,方法签名必须完全匹配,因此您必须在父方法使用unowned 的地方使用unowned,并且您不能只在父方法不使用可为空的地方引入可空(?)...
  • 即使在 error: PreferencesStyleProvider.get_icon_factory: no suitable method found to override 中添加 override 并删除可为空的结果。而如果我不能返回null,如何满足文档化的要求?
  • 你可以返回 null,因为 Gtk.IconFactory 是一个类类型,你有没有机会使用实验性的非 null 模式? VAPI 文件无论如何都需要修复,它应该在 vapi 文件中可以为空。
  • 另外我现在才意识到 Gtk.StyleProvider 不是一个抽象类,而是一个接口。很抱歉,实现接口override 不是必需的AFAIK。
  • 我在valac 命令中没有看到--enable-experimental-non-null

标签: c gtk vala gobject


【解决方案1】:

这在我的系统上编译没有错误或警告(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
  • 从返回类型中删除可空值。
  • 将 null 转换为实际的类类型。 (这并不漂亮,但问题出在 vapi 文件上。)
  • 为 out 参数分配一个虚拟值以使编译无警告;)

【讨论】:

  • 看来我选择了错误的类来使用我的第一个 Vala 界面体验!
  • 谢谢,它现在也适用于我!这清楚地解释了几个 Vala 概念!
  • 不客气,这就是 SO 的目的,我们一直期待帮助用户解决描述清楚的问题/疑问 :)。
猜你喜欢
  • 2012-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多