代码之家  ›  专栏  ›  技术社区  ›  John Tracid

如何在Perl哈希中存储null

  •  5
  • John Tracid  · 技术社区  · 9 年前

    我想在我的C代码(XS)中使用Perl哈希作为一个集合,所以我只需要在哈希中保留密钥。是否可以存储类似null或另一个常量值的值以避免创建不必要的值?

    类似于:

    int add_value(HV *hash, SV *value)
    {
        // just an example of key
        char key[64];
        sprintf(key, "%p", value);
        if (hv_exists(hash, key, strlen(key)) return 0;
    
        // here I need something instead of ?
        return hv_stores(hash, key, ?) != NULL;
    }
    

    可能的解决方案之一是存储值本身,但可能有一个特殊的常量 undef 或空。

    2 回复  |  直到 9 年前
        1
  •  5
  •   pilcrow    9 年前

    &PL_sv_undef 是未定义的值,但不幸的是,不能在哈希和数组中天真地使用它。引用 perlguts :

    通常,如果要在AV或HV中存储未定义的值,则不应使用&PL_sv_nundef,而是使用newSV函数创建一个新的未定义值,例如:

    av_store( av, 42, newSV(0) );
    hv_store( hv, "foo", 3, newSV(0), 0 );
    
        2
  •  4
  •   ikegami Gilles Quénot    9 年前

    &PL_sv_undef 这个 undef标量。它是只读的。你可能想要 新的undef标量,如使用创建的 newSV(0) [1] .

    返回的标量 新SV(0) 以refcount 1开始,当标量存储在其中时,哈希“占有” hv_stores ,所以不要 SvREFCNT_dec sv_2mortal 返回的标量。(如果您也将其存储在其他位置,请增加引用计数。)


    1. # "The" undef (A specific read-only variable that will never get deallocated)
      $ perl -MDevel::Peek -e'Dump(undef)'
      SV = NULL(0x0) at 0x3596700
        REFCNT = 2147483641
        FLAGS = (READONLY,PROTECT)
      
      # "An" undef (It's not the type of SVt_NULL that make it undef...)
      $ perl -MDevel::Peek -e'Dump($x)'
      SV = NULL(0x0) at 0x1bb7880
        REFCNT = 1
        FLAGS = ()
      
      # Another undef (... It's the lack of "OK" flags that make it undef)
      $ perl -MDevel::Peek -e'$x="abc"; $x=undef; Dump($x)'
      SV = PV(0x3d5f360) at 0x3d86590
        REFCNT = 1
        FLAGS = ()
        PV = 0
      
    推荐文章