全部!@ {}和[Hashtable] :: Clear()之间有什么区别?
我正在编写代码将标准INI文件结构转换为基于哈希表和数组的代码。例如,INI代码段如下所示:
[Book]
title="Moby Dick"
author="Herman Melville"
genre=fiction
genre=fantasy
[Book]
title="James and the Giant Peach"
author="Roald Dahl"
genre="fiction"
会是什么样子:
@{
"Book" = [
@{
"title" = ["Moby Dick"];
"author" = ["Herman Melville"];
"genre" = ["fiction","fantasy"]
},
@{
"title" = ["James and the Giant Peach"];
"author" = ["Roald Dahl"];
"genre" = ["fiction"]
}
]
}
我想解释有多个相同名字的部分和部分有多个相同名字的特性INI文件,因此这个数据结构。我知道我可以用一棵树来做同样的事情,但我并不关心它的速度,而且在我编写它时更容易实现。
这是通过更新他们的值的区间内关联的所有属性哈希表做(让我们称之为$items
),然后更新,与前述的那些哈希表的每个部分相关联的主要哈希表(我们称之为一个$results
)。散列表是全局性的,并且在迭代到新节时清除属性散列表。
虽然我编写了这样的代码,并且运行良好,但我却为了Powershell清除哈希表的方式而苦苦挣扎了几分钟。如果我使用$items.Clear()
,清除$items
,那么与$results
中的所有元素关联的散列表也会被清除。但是,如果我通过陈述[email protected]{}
“清除”它,则不会发生这种情况。
我假设发生这种情况是因为前一种情况下的哈希表都是对全局哈希表的引用,并且是后者中的独立对象。这是怎么回事?
代码在下面;对不起,如果任何这是令人困惑(并且它不是典型的Powershell语法)。与$items = $items.Clear()
替换$items = @{}
复制:
function parse ($file) {
$result = @{}
if (!(Test-Path $file)) {
write-host "File does not exist: $file"
} elseif (!($data = cat $file)) {
write-host "File has no data: $file"
} else {
$last_value = ""
$last_data = ""
$items = @{}
foreach ($line_raw in $data | ?{$_.Trim().Length -gt 0}) {
$line = $line_raw.TrimStart().TrimEnd()
$first_char = $line[0]
switch ($first_char) {
';' {
continue
}
'[' {
$key = $line -replace "\[|\]",""
if ($last_key) {
if (!($result.ContainsKey($last_key)))
{ $result.Add($last_key,@($items)) }
else
{ $result[$last_key] += $items }
if ($last_key -ne $key)
{ $items = @{} }
}
$last_key = $key
}
default {
$item , $data = $(
$sep = $line.indexOf('=')
$line.substring(0,$sep) , $line.substring($sep+1)
)
if (!$items.ContainsKey($item))
{ $items.Add($item,@($data)) }
else
{ $items[$item] += $data }
}
}
}
$result
}
}
我似乎无法复制该行为。你可以发布代码,了解你如何设置不同的哈希表? – DavidN