Julia Language
कार्य
खोज…
वाक्य - विन्यास
- f (n) = ...
- function f (n) ... अंत
- n :: प्रकार
- x -> ...
- f (n) do ... अंत
टिप्पणियों
सामान्य कार्यों के अलावा (जो सबसे आम हैं), वहाँ भी अंतर्निहित कार्य हैं। ऐसे कार्यों में शामिल is
, isa
, typeof
, throw
और इसी तरह के कार्य। अंतर्निहित कार्य आमतौर पर जूलिया के बजाय सी में लागू किए जाते हैं, इसलिए उन्हें प्रेषण के लिए तर्क प्रकारों पर विशेष नहीं किया जा सकता है।
एक नंबर को स्क्वायर करें
किसी फ़ंक्शन को परिभाषित करने के लिए यह सबसे आसान सिंटैक्स है:
square(n) = n * n
एक फ़ंक्शन को कॉल करने के लिए, गोल कोष्ठक (बीच में रिक्त स्थान के बिना) का उपयोग करें:
julia> square(10)
100
जूलिया में फ़ंक्शंस ऑब्जेक्ट हैं, और हम उन्हें REPL में किसी अन्य ऑब्जेक्ट के साथ दिखा सकते हैं:
julia> square
square (generic function with 1 method)
सभी जूलिया फ़ंक्शन सामान्य रूप से सामान्य (अन्यथा बहुरूपी के रूप में जाना जाता है ) हैं। हमारा square
फंक्शन फ्लोटिंग पॉइंट वैल्यू के साथ ही काम करता है:
julia> square(2.5)
6.25
... या यहां तक कि matrices :
julia> square([2 4
2 1])
2×2 Array{Int64,2}:
12 12
6 9
पुनरावर्ती कार्य
सरल पुनरावृत्ति
पुनरावर्तन और टर्नरी सशर्त संचालक का उपयोग करके, हम बिल्ट-इन factorial
फ़ंक्शन का एक वैकल्पिक कार्यान्वयन बना सकते हैं:
myfactorial(n) = n == 0 ? 1 : n * myfactorial(n - 1)
उपयोग:
julia> myfactorial(10)
3628800
पेड़ों के साथ काम करना
डेटा संरचनाओं, विशेष रूप से ट्री डेटा संरचनाओं पर पुनरावर्ती कार्य अक्सर सबसे उपयोगी होते हैं। चूंकि जूलिया में अभिव्यक्ति पेड़ की संरचनाएं हैं, इसलिए पुनरावर्तन मेटाप्रोग्रामिंग के लिए काफी उपयोगी हो सकता है। उदाहरण के लिए, नीचे दिए गए फ़ंक्शन में एक अभिव्यक्ति में उपयोग किए गए सभी प्रमुखों का एक सेट इकट्ठा होता है।
heads(ex::Expr) = reduce(∪, Set((ex.head,)), (heads(a) for a in ex.args))
heads(::Any) = Set{Symbol}()
हम जाँच कर सकते हैं कि हमारा कार्य उद्देश्य के अनुसार काम कर रहा है:
julia> heads(:(7 + 4x > 1 > A[0]))
Set(Symbol[:comparison,:ref,:call])
इस समारोह कॉम्पैक्ट है और इस तरह के रूप में और अधिक उन्नत तकनीकों, की एक किस्म का उपयोग करता है reduce
उच्च आदेश समारोह , Set
डेटा प्रकार, और जनरेटर भाव।
डिस्पैच का परिचय
हम एक तर्क के प्रकार पर प्रेषण के लिए ::
सिंटैक्स का उपयोग कर सकते हैं।
describe(n::Integer) = "integer $n"
describe(n::AbstractFloat) = "floating point $n"
उपयोग:
julia> describe(10)
"integer 10"
julia> describe(1.0)
"floating point 1.0"
कई भाषाओं के विपरीत, जो आम तौर पर या तो स्टेटिक मल्टीपल डिस्पैच या डायनेमिक सिंगल डिस्पैच प्रदान करती हैं, जूलिया में फुल डायनामिक मल्टीपल डिस्पैच होता है। यही है, कार्यों को एक से अधिक तर्क के लिए विशेष किया जा सकता है। यह काम में आता है जब कुछ विशेष प्रकारों के संचालन के लिए विशेष तरीकों को परिभाषित करता है, और अन्य प्रकारों के लिए फ़ॉलबैक तरीके।
describe(n::Integer, m::Integer) = "integers n=$n and m=$m"
describe(n, m::Integer) = "only m=$m is an integer"
describe(n::Integer, m) = "only n=$n is an integer"
उपयोग:
julia> describe(10, 'x')
"only n=10 is an integer"
julia> describe('x', 10)
"only m=10 is an integer"
julia> describe(10, 10)
"integers n=10 and m=10"
वैकल्पिक तर्क
जूलिया कार्यों को वैकल्पिक तर्क देने की अनुमति देता है। पर्दे के पीछे, इसे कई प्रेषण के एक और विशेष मामले के रूप में लागू किया जाता है। उदाहरण के लिए, आइए लोकप्रिय Fizz Buzz समस्या को हल करें । डिफ़ॉल्ट रूप से, हम इसे 1:10
की सीमा में संख्याओं के लिए करेंगे, लेकिन यदि आवश्यक हो तो हम एक अलग मूल्य की अनुमति देंगे। हम Fizz
या Buzz
लिए विभिन्न वाक्यांशों का उपयोग करने की अनुमति भी देंगे।
function fizzbuzz(xs=1:10, fizz="Fizz", buzz="Buzz")
for i in xs
if i % 15 == 0
println(fizz, buzz)
elseif i % 3 == 0
println(fizz)
elseif i % 5 == 0
println(buzz)
else
println(i)
end
end
end
यदि हम REPL में fizzbuzz
का निरीक्षण करते हैं, तो यह कहता है कि चार विधियाँ हैं। अनुमतियों के प्रत्येक संयोजन के लिए एक विधि बनाई गई थी।
julia> fizzbuzz
fizzbuzz (generic function with 4 methods)
julia> methods(fizzbuzz)
# 4 methods for generic function "fizzbuzz":
fizzbuzz() at REPL[96]:2
fizzbuzz(xs) at REPL[96]:2
fizzbuzz(xs, fizz) at REPL[96]:2
fizzbuzz(xs, fizz, buzz) at REPL[96]:2
हम सत्यापित कर सकते हैं कि हमारे डिफ़ॉल्ट मानों का उपयोग तब किया जाता है जब कोई पैरामीटर प्रदान नहीं किया जाता है:
julia> fizzbuzz()
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
लेकिन अगर हम उन्हें प्रदान करते हैं तो वैकल्पिक पैरामीटर स्वीकार किए जाते हैं और उनका सम्मान किया जाता है:
julia> fizzbuzz(5:8, "fuzz", "bizz")
bizz
fuzz
7
8
पैरामीट्रिक डिस्पैच
यह अक्सर ऐसा होता है कि फ़ंक्शन को पैरामीट्रिक प्रकारों, जैसे Vector{T}
या Dict{K,V}
पर भेजा जाना चाहिए, लेकिन टाइप पैरामीटर निश्चित नहीं हैं। पैरामीट्रिक प्रेषण का उपयोग करके इस मामले से निपटा जा सकता है:
julia> foo{T<:Number}(xs::Vector{T}) = @show xs .+ 1
foo (generic function with 1 method)
julia> foo(xs::Vector) = @show xs
foo (generic function with 2 methods)
julia> foo([1, 2, 3])
xs .+ 1 = [2,3,4]
3-element Array{Int64,1}:
2
3
4
julia> foo([1.0, 2.0, 3.0])
xs .+ 1 = [2.0,3.0,4.0]
3-element Array{Float64,1}:
2.0
3.0
4.0
julia> foo(["x", "y", "z"])
xs = String["x","y","z"]
3-element Array{String,1}:
"x"
"y"
"z"
किसी को केवल xs::Vector{Number}
लिखने के लिए लुभाया जा सकता है xs::Vector{Number}
। लेकिन यह केवल उन वस्तुओं के लिए काम करता है जिनका प्रकार स्पष्ट रूप से Vector{Number}
:
julia> isa(Number[1, 2], Vector{Number})
true
julia> isa(Int[1, 2], Vector{Number})
false
इस की वजह से है पैरामीट्रिक निश्चरता : वस्तु Int[1, 2]
नहीं एक है Vector{Number}
, क्योंकि यह केवल शामिल कर सकते हैं Int
, रों जबकि एक Vector{Number}
संख्या के किसी भी प्रकार को रोकने के लिए सक्षम होने के लिए उम्मीद होगी।
जेनेरिक कोड लेखन
डिस्पैच एक अविश्वसनीय रूप से शक्तिशाली विशेषता है, लेकिन अक्सर यह सामान्य कोड लिखना बेहतर होता है जो प्रत्येक प्रकार के लिए विशेषज्ञता कोड के बजाय सभी प्रकार के लिए काम करता है। जेनेरिक कोड लिखने से कोड के दोहराव से बचा जाता है।
उदाहरण के लिए, यहाँ एक वेक्टर के वर्गों के योग की गणना करने के लिए कोड है:
function sumsq(v::Vector{Int})
s = 0
for x in v
s += x ^ 2
end
s
end
लेकिन यह कोड केवल Int
s के वेक्टर के लिए काम करता है। यह UnitRange
पर काम नहीं करेगा:
julia> sumsq(1:10)
ERROR: MethodError: no method matching sumsq(::UnitRange{Int64})
Closest candidates are:
sumsq(::Array{Int64,1}) at REPL[8]:2
यह एक Vector{Float64}
पर काम नहीं करेगा:
julia> sumsq([1.0, 2.0])
ERROR: MethodError: no method matching sumsq(::Array{Float64,1})
Closest candidates are:
sumsq(::Array{Int64,1}) at REPL[8]:2
इस sumsq
फ़ंक्शन को लिखने का एक बेहतर तरीका होना चाहिए
function sumsq(v::AbstractVector)
s = zero(eltype(v))
for x in v
s += x ^ 2
end
s
end
यह ऊपर सूचीबद्ध दो मामलों पर काम करेगा। लेकिन कुछ संग्रह हैं जो हम चाहते हैं कि किसी भी अर्थ में वे वैक्टर नहीं हैं। उदाहरण के लिए,
julia> sumsq(take(countfrom(1), 100))
ERROR: MethodError: no method matching sumsq(::Base.Take{Base.Count{Int64}})
Closest candidates are:
sumsq(::Array{Int64,1}) at REPL[8]:2
sumsq(::AbstractArray{T,1}) at REPL[11]:2
दिखाता है कि हम एक आलसी चलने के वर्गों को योग नहीं कर सकते हैं।
एक और भी अधिक सामान्य कार्यान्वयन बस है
function sumsq(v)
s = zero(eltype(v))
for x in v
s += x ^ 2
end
s
end
जो सभी मामलों में काम करता है:
julia> sumsq(take(countfrom(1), 100))
338350
यह सबसे मुहावरेदार जूलिया कोड है, और सभी प्रकार की स्थितियों को संभाल सकता है। कुछ अन्य भाषाओं में, प्रकार के एनोटेशन को हटाने से प्रदर्शन प्रभावित हो सकता है, लेकिन जूलिया में ऐसा नहीं है; प्रदर्शन के लिए केवल प्रकार की स्थिरता महत्वपूर्ण है।
इंपीरियल फैक्टरियल
मल्टी-लाइन फ़ंक्शंस को परिभाषित करने के लिए एक लंबा-फॉर्म सिंटैक्स उपलब्ध है। यह उपयोगी हो सकता है जब हम लूप जैसी अनिवार्यता संरचनाओं का उपयोग करते हैं। पूंछ की स्थिति में अभिव्यक्ति वापस आ गई है। उदाहरण के लिए, नीचे का फ़ंक्शन लूप के लिए कुछ पूर्णांक n
के भाज्य की गणना करने के for
उपयोग करता है:
function myfactorial(n)
fact = one(n)
for m in 1:n
fact *= m
end
fact
end
उपयोग:
julia> myfactorial(10)
3628800
लंबे कार्यों में, return
स्टेटमेंट का उपयोग किया जाना आम है। पूंछ की स्थिति में return
स्टेटमेंट आवश्यक नहीं है, लेकिन यह अभी भी कभी-कभी स्पष्टता के लिए उपयोग किया जाता है। उदाहरण के लिए, उपरोक्त फ़ंक्शन लिखने का एक और तरीका होगा
function myfactorial(n)
fact = one(n)
for m in 1:n
fact *= m
end
return fact
end
जो ऊपर दिए गए कार्य के समान है।
अनाम कार्य
तीर का सिंटैक्स
बेनामी फ़ंक्शंस ->
सिंटैक्स का उपयोग करके बनाया जा सकता है। यह फ़ंक्शंस को उच्च-ऑर्डर फ़ंक्शंस में पास करने के लिए उपयोगी है, जैसे कि map
फ़ंक्शन। नीचे दिए गए फ़ंक्शन में सरणी A
में प्रत्येक संख्या के वर्ग की गणना की गई है।
squareall(A) = map(x -> x ^ 2, A)
इस फ़ंक्शन का उपयोग करने का एक उदाहरण:
julia> squareall(1:10)
10-element Array{Int64,1}:
1
4
9
16
25
36
49
64
81
100
मल्टीलाइन सिंटैक्स
function
सिंटैक्स का उपयोग करके बहु-अज्ञात अनाम फ़ंक्शन बनाए जा सकते हैं। उदाहरण के लिए, निम्न उदाहरण पहले n
संख्याओं के भाज्य की गणना करता है, लेकिन इसमें निर्मित factorial
बजाय एक अनाम फ़ंक्शन का उपयोग किया जाता है।
julia> map(function (n)
product = one(n)
for i in 1:n
product *= i
end
product
end, 1:10)
10-element Array{Int64,1}:
1
2
6
24
120
720
5040
40320
362880
3628800
वाक्यविन्यास को अवरुद्ध करें
क्योंकि यह तो एक समारोह के लिए पहले तर्क के रूप में एक गुमनाम समारोह पारित करने के लिए आम बात है, वहाँ एक है do
ब्लॉक वाक्य रचना। वाक्य रचना
map(A) do x
x ^ 2
end
के बराबर है
map(x -> x ^ 2, A)
लेकिन पूर्व कई स्थितियों में अधिक स्पष्ट हो सकता है, खासकर अगर अनाम फ़ंक्शन में बहुत अधिक गणना की जा रही है। do
ब्लॉक वाक्य रचना के लिए विशेष रूप से उपयोगी है फ़ाइल इनपुट और आउटपुट संसाधन प्रबंधन कारणों के लिए।