2015-06-26 52 views
5

我需要處理哈希值取決於值類型。這裏是有問題的代碼:如何在Perl中處理哈希值類型XS

I32 keys = hv_iterinit(hash); 
for (I32 i = 0; i < keys; i++) 
{ 
    char *key = NULL; 
    I32 key_length = 0; 
    SV *value = hv_iternextsv(hash, &key, &key_length); 
    // SvROK(value); 
    if (SvTYPE(SvRV(value)) < SVt_PVAV) 
    { 
    // handle scalar 
    printf("key %s has scalar value\n", key); 
    } 
    else if (SvTYPE(SvRV(value)) == SVt_PVAV) 
    { 
    // handle array 
    printf("key %s has array value\n", key); 
    } 
    else if (SvTYPE(SvRV(value)) == SVt_PVHV) 
    { 
    // handle hash 
    printf("key %s has hash value\n", key); 
    } 
} 

如果我不使用註釋行,我有標量值的問題。例如具有以下哈希{a => "b", c => {d => "e"}}是產生輸出:

key c has hash value 
key d has scalar value 

因此,這裏是我的問題:

  1. 難道我們總是從hv_iternextsv()返回的引用,有時它返回標?
  2. 爲什麼我看不到關鍵字a的標量值輸出。

更新。

我的錯誤是與hv_iternextsv()的結果一起工作。我在想這總是一個參考。這裏是如何工作的代碼如下所示:

I32 keys = hv_iterinit(hash); 
for (I32 i = 0; i < keys; i++) 
{ 
    char *key = NULL; 
    I32 key_length = 0; 
    SV *value = hv_iternextsv(hash, &key, &key_length); 
    if (!SvROK(value)) 
    { 
    // handle scalar 
    } 
    else 
    { 
    if (SvTYPE(SvRV(value)) == SVt_PVAV) 
    { 
     // handle array 
    } 
    else if (SvTYPE(SvRV(value)) == SVt_PVHV) 
    { 
     // handle hash 
    } 
    } 
} 
+0

我期待你的貼缺少一些括號,因爲這將無法編譯。也許你的意思是:'if(SvTYPE(SvRV(value))== SVt_PVAV)'? – LeoNerd

+0

代碼更新,謝謝。 –

+0

@ikegami我更新了我的問題。問題,我沒有看到關鍵'a'的標量值輸出。 –

回答

3

難道我們總是從hv_iternextsv()返回的引用,有時它返回標?

它總是返回一個標量。哈希值只能是標量。這些標量可以是參考($h{x} = [];),但不一定是($h{y} = 123;)。

爲什麼我看不到關鍵a的標量值輸出。

有沒有辦法,你可能可能回到你說的它做什麼,看到你的哈希沒有命名d關鍵。對於您提供的哈希值,你的代碼輸出以下:

key a has scalar value 
key c has hash value 

但它比什麼都重要,你答對了巧合。 SvTYPE(SvRV(value))value不是參考?這是沒有意義的!固定的代碼如下:

use strict; 
use warnings; 

use Inline C => <<'__EOI__'; 

    void print_keys(HV* hash) { 
    char *key; 
    I32 key_length; 
    SV *value; 

    hv_iterinit(hash); 
    while (value = hv_iternextsv(hash, &key, &key_length)) { 
     if (SvROK(value)) { 
     SV * const referenced = SvRV(value); 
     if (SvTYPE(referenced) == SVt_PVAV) { 
      printf("The value at key %s is reference to an array\n", key); 
     } 
     else if (SvTYPE(referenced) == SVt_PVHV) { 
      printf("The value at key %s is a reference to a hash\n", key); 
     } 
     else { 
      printf("The value at key %s is a reference\n", key); 
     } 
     } else { 
     printf("The value at key %s is not a reference\n", key); 
     } 
    } 
    } 

__EOI__ 

print_keys({a => "b", c => {d => "e"}}); 

輸出:

The value at key a is not a reference 
The value at key c is a reference to a hash 
+0

更新了我的答案。 – ikegami

+0

我再次調用該代碼以獲得散列,因此它會生成該輸出。我添加了引用檢查,它顯示鍵「a」的值不是引用。所以我的第二個問題仍然有效。 –

+0

不要說謊。它被回答了,但你在一小時後改變了它。如果您有新問題,請在評論中或作爲適當的問題提問。 //你可以使用'SvTYPE'來檢查標量的類型,但是你爲什麼要這麼做。如果你想要一個字符串,使用'SvPVutf8'。如果你想要一個整數,使用'SvIV'等。你不應該在乎它是如何存儲的。 – ikegami