在朱莉婭,說我有一個變量的object_id
但已經忘記了它的名字,我怎麼可以檢索使用ID的對象?我怎麼能在朱莉婭的ID檢索對象
I.e.我想要some_id = object_id(some_object)
的倒數。
在朱莉婭,說我有一個變量的object_id
但已經忘記了它的名字,我怎麼可以檢索使用ID的對象?我怎麼能在朱莉婭的ID檢索對象
I.e.我想要some_id = object_id(some_object)
的倒數。
由於@DanGetz在評論中說,object_id
是散列函數,並設計爲不是可逆的。 @phg也是正確的,ObjectIdDict
正是用於這一目的(這是documented雖然沒有在手冊中討論了):
ObjectIdDict([itr])
ObjectIdDict()
構造一個哈希表,其中鍵是(總是) 對象身份。不像Dict
它沒有參數的關鍵和 值類型,因此它的eltype總是Pair{Any,Any}
。進一步的幫助,請參見
Dict
。
換句話說,它使用object_id
作爲散列函數散列對象===
。如果你有一個ObjectIdDict
,並且使用你遇到的對象作爲它的鍵,那麼你可以將它們保留在周圍並在ObjectIdDict
之外將它們恢復。
但是,這聽起來像你想要做到這一點,沒有明確的ObjectIdDict
只是詢問曾創建的對象有給定的object_id
。如果是這樣,請考慮這個想法實驗:如果每個對象始終可以從其object_id
中恢復,那麼系統永遠不會丟棄任何對象,因爲程序通過ID來請求該對象總是可能的。所以你永遠無法收集任何垃圾,並且每個程序的內存使用情況都會迅速擴展,以便使用所有的RAM和磁盤空間。這相當於有一個單一的全球ObjectIdDict
,你把每一個對象創建到。因此,反過來,object_id
函數不需要釋放任何對象,這意味着你需要無限的內存。
即使我們有無限的記憶,還有更深層次的問題。對象存在意味着什麼?在存在優化編譯器的情況下,這個問題沒有明確的答案。從程序員的角度來看,一個對象通常會被創建和操作,但實際上 - 從硬件的角度來看 - 它永遠不會被創建。考慮一下這個功能,構建了一個複雜的號碼,然後使用它進行一個簡單的計算:
julia> function f(y::Real)
z = Complex(0,y)
w = 2z*im
return real(w)
end
f (generic function with 1 method)
julia> foo(123)
-246
從程序員的角度來看,這構建了複數z
,然後構建2z
,然後2z*im
,最後構建real(2z*im)
並返回該值。所以所有這些值都應該插入到「天空中的Great ObjectIdDict」中。但他們真的構建?下面是應用於Int
此功能的LLVM代碼:所有構造
julia> @code_llvm foo(123)
define i64 @julia_foo_60833(i64) #0 !dbg !5 {
top:
%1 = shl i64 %0, 1
%2 = sub i64 0, %1
ret i64 %2
}
沒有Complex
值!相反,所有的工作都是內聯的,而不是實際完成的。整個計算歸結爲將參數加倍(通過將其左移一位)並將其反轉(通過從零中減去它)。這種優化可以首先完成,因爲中間步驟沒有可觀察到的副作用。編譯器知道無法區分實際構造複雜值和對它們進行操作,只是做了幾個整數運算 - 只要最終結果總是相同。隱在「天空之大ObjectIdDict」的想法是,似乎是實際製造的所有對象構造並插入到一個大的,永久性數據結構的假設 - 這是一個巨大的副作用。因此,不僅是從其ID中恢復對象與垃圾收集不兼容,它還與幾乎所有可以想象的程序優化都不兼容。
除此之外,唯一一個可以設想反相object_id
是計算上的需求,而不是因爲它們是創建對象保存其反轉的圖像。這將解決內存和優化問題。當然,這是不可能的,因爲有無限多的可能對象,但只有有限數量的對象ID。您是微乎其微不可能真正遇到兩個對象在程序中相同的ID,但ID空間的有限性意味着反轉散列函數原則是不可能因爲每個ID值的原像包含潛在對象無限數量的。
我可能已經反駁了功能遠遠超過必要性的可能性,但它導致了一些有趣的思想實驗,並且我希望這有助於 - 或者至少是令人興奮的。實際的答案是,沒有辦法繞過明確存儲每個對象,你可能想要回到ObjectIdDict
。
'object_id'是散列函數,這通常意味着它不能容易地反轉。另外,'some_object'可能不是一個變量,而是一個不可變的,它不會在後面存在。例如,'object_id(123)'返回一個值,但'123'不是一個變量,並且稍後在特定的內存位置不存在。想想解決問題的另一種方法可能會更好,可能使用Dict並將變量放入其中,並使用它們的'object_id(...)'作爲鍵。 –
有一個'ObjectIdDict',它可能用於'object_id'存儲。但我認爲這是相當無證的。 – phg