मेरे पास एक मॉड्यूल है जिसे मैं वैश्विक चर के सेट के रूप में उपयोग करना चाहता हूं।

फ़ाइल Global.jl:

module Global

    export data
    export dataLoaded

    data = zeros(Int32, 20, 12, 31, 24, 60, 5);

    dataLoaded = false;

end

फ़ाइल main2.jl:

include("Global.jl")
import .Global


println(Global.data[10,1,1,1,1,1])
println(Global.dataLoaded)

Global.data[10,1,1,1,1,1] = 5
println(Global.data[10,1,1,1,1,1])

Global.dataLoaded = true
println(Global.dataLoaded)

मैं उम्मीद नहीं कर रहा था कि dataLoaded को data की तरह बदला नहीं जा सकता। क्या dataLoaded को बदलने की अनुमति देने का कोई तरीका है?

$ /usr/local/julia-1.2.0/bin/julia main2.jl
0
false
5
ERROR: LoadError: cannot assign variables in other modules
Stacktrace:
 [1] setproperty!(::Module, ::Symbol, ::Bool) at ./Base.jl:14
 [2] top-level scope at /usr/home/.../main2.jl:11
 [3] include at ./boot.jl:328 [inlined]
 [4] include_relative(::Module, ::String) at ./loading.jl:1094
 [5] include(::Module, ::String) at ./Base.jl:31
 [6] exec_options(::Base.JLOptions) at ./client.jl:295
 [7] _start() at ./client.jl:464
in expression starting at /usr/home/.../main2.jl:11
2
M.E. 15 सितंबर 2019, 00:46

1 उत्तर

सबसे बढ़िया उत्तर

जैसा कि मैंने वैश्विक चरों को परिभाषित करने में टिप्पणी की है बाद में जूलिया में साझा करने के लिए आपको मॉड्यूल के बाहर से एक चर के बंधन को बदलने की अनुमति नहीं है।

सबसे पहले, यह समझाने के लिए कि क्या हो रहा है, इस पर विचार करें:

x = [1,2,3]
x[1] = 10

दूसरा ऑपरेशन x[1] = 10 x के बंधन को नहीं बदलता है, यह केवल वेक्टर x के पहले तत्व में संग्रहीत मान को बदलता है (क्योंकि वैक्टर परस्पर हैं)।

दूसरी ओर लेखन:

y = 1
y = 10

पहले y को एक मान के लिए परिभाषित करता है 1 (प्रकार का Int जो अपरिवर्तनीय है), और फिर y = 10 10 को रखने के लिए y को फिर से बांधता है।

अब - आप अपनी समस्या का समाधान कैसे कर सकते हैं। दो दृष्टिकोण हैं:

सबसे पहले अपने Global मॉड्यूल के अंदर एक सेटर फ़ंक्शन को इस तरह परिभाषित करना है:

function setdataloaded(value::Bool)
    global dataLoaded = value
end

जैसा कि setdataloaded को Global मॉड्यूल में परिभाषित किया गया है, यह इस मॉड्यूल में चर के बाइंडिंग को बदल सकता है। फिर आप dataLoaded के मान को बदलने के लिए मॉड्यूल के बाहर से setdataloaded को कॉल कर सकते हैं।

दूसरा एक अपरिवर्तनीय कंटेनर के बजाय एक परिवर्तनशील कंटेनर का उपयोग करना है। सबसे सरल Ref है। तो आप परिभाषित कर सकते हैं:

dataLoaded = Ref(false)

और फिर आप dataLoaded[] के रूप में मान प्राप्त कर सकते हैं और Global मॉड्यूल के बाहर से इसका मान dataLoaded[] = true सेट कर सकते हैं (क्योंकि इस बार आप कंटेनर की सामग्री को बदल रहे हैं और रिबाइंड नहीं कर रहे हैं dataLoaded)।

संपादित करें

जैसा कि तकनीकी रूप से टिप्पणी में उल्लेख किया गया है, आप इस मॉड्यूल के बाहर कोड से भी Global मॉड्यूल के भीतर dataLoaded = 10 अभिव्यक्ति का मूल्यांकन कर सकते हैं:

@eval Global dataLoaded = 10

या

Global.eval(:(dataLoaded = 10))

इस तथ्य का उपयोग करते हुए कि प्रत्येक मॉड्यूल (baremodule को छोड़कर लेकिन यह एक दुर्लभ उपयोग का मामला है) की अपनी मॉड्यूल-स्थानीय परिभाषा eval है।

एक तरह से eval दृष्टिकोण एक तरह का पहला दृष्टिकोण है जिसका मैंने वर्णन किया है (एक सेटर फ़ंक्शन का उपयोग करके) जो डिफ़ॉल्ट रूप से अनुमत है।

3
Bogumił Kamiński 15 सितंबर 2019, 10:00