انواع داده‌ها و ساختارهای اساسی در جولیا

جولیا (Julia) یک زبان برنامه‌نویسی پویا، سطح بالا و با کارایی بالا است که به طور فزاینده‌ای در حوزه‌های هوش مصنوعی،  علم داده و یادگیری ماشین  محبوبیت یافته است. یکی از دلایل اصلی موفقیت جولیا، سیستم انواع داده‌ای قدرتمند و انعطاف‌پذیر آن است. درک عمیق انواع داده‌ها و ساختارهای اساسی در جولیا، کلید نوشتن کدهای کارآمد، خوانا و قابل نگهداری است. این مقاله به بررسی جامع انواع داده‌های اولیه، ترکیبی و ساختارهای داده کلیدی در جولیا می‌پردازد.

 

1. انواع داده‌های اولیه (Primitive Data Types)

انواع داده‌های اولیه، بلوک‌های سازنده اصلی در هر زبان برنامه‌نویسی هستند. جولیا نیز از مجموعه‌ای از انواع داده‌های اولیه پشتیبانی می‌کند که شامل اعداد صحیح، اعداد اعشاری، بولین‌ها و کاراکترها می‌شود.

1.1. اعداد صحیح (Integers)

جولیا از اعداد صحیح با اندازه‌های مختلف پشتیبانی می‌کند که هم با علامت (signed) و هم بدون علامت (unsigned) هستند. این انعطاف‌پذیری به برنامه‌نویس اجازه می‌دهد تا نوع داده‌ای را انتخاب کند که متناسب با محدوده مقادیر مورد نیاز باشد و از هدر رفتن حافظه جلوگیری کند.

 

اعداد صحیح با علامت:

* `Int8`: 8 بیتی، از -128 تا 127
* `Int16`: 16 بیتی، از -32768 تا 32767
* `Int32`: 32 بیتی، از -2,147,483,648 تا 2,147,483,647
* `Int64`: 64 بیتی، از -9,223,372,036,854,775,808 تا 9,223,372,036,854,775,807
* `Int128`: 128 بیتی (معمولاً در دسترس نیست مگر در سخت‌افزارهای خاص)
* `Int`: نوع پیش‌فرض عدد صحیح، که معمولاً با معماری سیستم (32 یا 64 بیتی) مطابقت دارد.

 

اعداد صحیح بدون علامت:

* `UInt8`: 8 بیتی، از 0 تا 255
* `UInt16`: 16 بیتی، از 0 تا 65535
* `UInt32`: 32 بیتی، از 0 تا 4,294,967,295
* `UInt64`: 64 بیتی، از 0 تا 18,446,744,073,709,551,615
* `UInt128`: 128 بیتی (معمولاً در دسترس نیست)
* `UInt`: نوع پیش‌فرض عدد صحیح بدون علامت.

مثال:

a = 10 # نوع Int64 (معمولاً)
b = UInt8(200) # نوع UInt8
c = -50 # نوع Int64 (معمولاً)

 

1.2. اعداد اعشاری (Floating-Point Numbers)

اعداد اعشاری برای نمایش مقادیر غیرصحیح استفاده می‌شوند. جولیا از استانداردهای IEEE 754 برای اعداد اعشاری پشتیبانی می‌کند.

* `Float16`: 16 بیتی (کمتر رایج)
* `Float32`: 32 بیتی
* `Float64`: 64 بیتی (نوع پیش‌فرض)
* `BigFloat`: برای دقت دلخواه (arbitrary-precision)

مثال:

pi_val = 3.14159 # نوع Float64
temp = Float32(25.5) # نوع Float32
large_num = BigFloat("1.23456789012345678901234567890123456789") # دقت دلخواه

 

1.3. اعداد مختلط (Complex Numbers)

جولیا از اعداد مختلط پشتیبانی می‌کند که از دو بخش حقیقی و موهومی تشکیل شده‌اند.

* `Complex{Float32}`: اعداد مختلط با بخش‌های 32 بیتی.
* `Complex{Float64}`: اعداد مختلط با بخش‌های 64 بیتی (نوع پیش‌فرض).
* `Complex{Int}`: اعداد مختلط با بخش‌های صحیح.

مثال:

z = 2 + 3im # نوع Complex{Int} (اگر 2 و 3 صحیح باشند)
z_float = 1.5 + 2.5im # نوع Complex{Float64}

 

1.4. اعداد گویا (Rational Numbers)

جولیا امکان نمایش دقیق اعداد گویا را با استفاده از نسبت دو عدد صحیح فراهم می‌کند.

* `Rational{Int}`: نسبت دو عدد صحیح (نوع پیش‌فرض).

مثال:

ratio = 3 // 4 # نوع Rational{Int}
println(ratio) # خروجی: 3//4
println(Float64(ratio)) # خروجی: 0.75

 

1.5. بولین‌ها (Booleans)

مقادیر بولین برای نمایش درست (true) یا نادرست (false) استفاده می‌شوند.

* `Bool`

مثال:

is_active = true
is_empty = false

 

1.6. کاراکترها (Characters)

برای نمایش یک حرف یا نماد واحد استفاده می‌شود. جولیا از یونیکد (Unicode) به طور کامل پشتیبانی می‌کند.

* `Char`

مثال:

first_letter = 'A'
unicode_char = '\u20AC' # نماد یورو

2. انواع داده‌های ترکیبی (Composite Data Types)

انواع داده‌های ترکیبی از ترکیب انواع داده‌های دیگر ساخته می‌شوند و امکان سازماندهی و نمایش ساختارهای پیچیده‌تر را فراهم می‌کنند.

2.1. آرایه‌ها (Arrays)

آرایه‌ها یکی از مهم‌ترین ساختارهای داده در جولیا هستند و برای ذخیره مجموعه‌ای از مقادیر از یک نوع مشخص استفاده می‌شوند. جولیا انواع مختلفی از آرایه‌ها را پشتیبانی می‌کند، از جمله آرایه‌های چندبعدی.

آرایه‌های یک‌بعدی (Vectors):

vec_int = [1, 2, 3, 4] # نوع Vector{Int64}
vec_float = [1.0, 2.5, 3.1] # نوع Vector{Float64}

 

آرایه‌های چندبعدی (Matrices, Tensors)

matrix = [1 2; 3 4] # نوع Matrix{Int64} (2x2)
tensor = zeros(Int, 2, 3, 4) # یک تنسور 3 بعدی با ابعاد 2x3x4 پر از صفر

 

نواع خاص آرایه:

* `Range`: برای نمایش دنباله‌ای از اعداد (مثلاً `1:5`).
* `UnitRange`: نوع خاصی از `Range`.
* `CartesianIndex`: برای اندیس‌گذاری چندبعدی.

 

نکات کلیدی در مورد آرایه‌ها در جولیا:

 

مرتب‌سازی ستونی (Column-major order): آرایه‌ها در جولیا به صورت ستونی مرتب‌سازی می‌شوند، که برای عملیات ماتریسی بهینه است.
نوع داده یکنواخت: در یک آرایه، تمام عناصر باید از یک نوع باشند. اگر انواع مختلفی را در یک آرایه قرار دهید، جولیا سعی می‌کند آن‌ها را به یک نوع مشترک تبدیل کند یا خطایی ایجاد کند.
اندیس‌گذاری از 1: مانند بسیاری از زبان‌های علمی، اندیس‌گذاری در جولیا از 1 شروع می‌شود.
اندازه و ابعاد: می‌توان با `size()` ابعاد و با `length()` تعداد عناصر را بدست آورد.

 

2.2. تاپل‌ها (Tuples)

تاپل‌ها مجموعه‌های مرتب و *تغییرناپذیر* (immutable) از عناصر هستند که می‌توانند انواع داده‌های متفاوتی داشته باشند.

تعریف تاپل:

my_tuple = (1, "hello", 3.14) # نوع Tuple{Int64, String, Float64}

دسترسی به عناصر: با استفاده از اندیس‌گذاری (از 1 شروع می‌شود) یا با نام‌گذاری (در تاپل‌های نام‌گذاری شده).

println(my_tuple[1]) # خروجی: 1
println(my_tuple[2]) # خروجی: hello

 

تاپل‌های نام‌گذاری شده (Named Tuples):

person = (name="Alice", age=30) # نوع NamedTuple{(:name, :age), Tuple{String, Int64}}
println(person.name) # خروجی: Alice
println(person.age) # خروجی: 30

 

کاربرد تاپل‌ها:

* بازگرداندن چند مقدار از یک تابع.
* ذخیره مجموعه‌ای از مقادیر مرتبط که نباید تغییر کنند.

 

2.3. دیکشنری‌ها (Dictionaries)

دیکشنری‌ها (که در جولیا به عنوان `Dict` شناخته می‌شوند) ساختارهای داده‌ای کلید-مقدار (key-value) هستند. هر کلید منحصر به فرد است و به یک مقدار مرتبط است.

 

تعریف دیکشنری:

grades = Dict("Alice" => 95, "Bob" => 88, "Charlie" => 76) # نوع Dict{String, Int64}

 

دسترسی به مقادیر: با استفاده از کلید.

println(grades["Alice"]) # خروجی: 95

 

اضافه کردن/تغییر عناصر:

grades["David"] = 92
grades["Alice"] = 98 # به‌روزرسانی مقدار

 

بررسی وجود کلید:

haskey(grades, "Bob") # خروجی: true
haskey(grades, "Eve") # خروجی: false

 

کاربرد دیکشنری‌ها:

* نمایش نگاشت‌ها (mappings) و روابط بین داده‌ها.
* ذخیره تنظیمات و پیکربندی‌ها.
* پیاده‌سازی جداول جستجو (lookup tables).

 

2.4. مجموعه‌ها (Sets)

مجموعه‌ها ساختارهای داده‌ای هستند که شامل عناصر منحصر به فرد و *مرتب نشده* می‌باشند.

تعریف مجموعه:

unique_numbers = Set([1, 2, 2, 3, 4, 4, 4]) # نوع Set{Int64}
println(unique_numbers) # خروجی: Set([1, 2, 3, 4])

عملیات مجموعه‌ای:
* `union()`: اجتماع دو مجموعه.
* `intersect()`: اشتراک دو مجموعه.
* `setdiff()`: تفاضل دو مجموعه.
* `in`: بررسی عضویت یک عنصر در مجموعه.

 

کاربرد مجموعه‌ها:

* حذف مقادیر تکراری.
* انجام عملیات منطقی روی مجموعه‌ها.

 

3. رشته‌ها (Strings)

رشته‌ها دنباله‌ای از کاراکترها هستند. جولیا از رشته‌های یونیکد به طور کامل پشتیبانی می‌کند.

رشته‌های ثابت (Immutable Strings): با استفاده از کوتیشن دوتایی (`”`).

str1 = "Hello, Julia!" # نوع String

رشته‌های چندخطی (Multi-line Strings):

multiline_str = """This is a
multi-line string."""

رشته‌های خام (Raw Strings): کاراکترهای ویژه مانند `\n` را تفسیر نمی‌کنند.

raw_str = r"C:\Users\Documents"

جایگذاری در رشته‌ها (String Interpolation): با استفاده از `$`

name = "World"
greeting = "Hello, $name!" # خروجی: "Hello, World!"
value = 10
message = "The value is $(value * 2)." # خروجی: "The value is 20."

عملگرهای رشته‌ای:

* `+`: الحاق (concatenation).
* `*`: تکرار رشته (مثلاً `repeat(“a”, 3)` می‌شود `”aaa”`).

 

 

4. ساختارهای سفارشی (Custom Structs)

جولیا به شما اجازه می‌دهد تا انواع داده‌های سفارشی خود را با استفاده از کلمه کلیدی `struct` تعریف کنید. این ساختارها به شما امکان می‌دهند داده‌ها و رفتارهای مرتبط را در یک واحد منطقی گروه‌بندی کنید.

تعریف struct:

struct Point
x::Float64
y::Float64
end

در اینجا، `Point` یک نوع داده سفارشی است که دو فیلد `x` و `y` از نوع `Float64` دارد.

 

 

ایجاد نمونه (instance) از struct:

p1 = Point(1.0, 2.0) # ایجاد یک نقطه در مختصات (1.0, 2.0)

 

دسترسی به فیلدها:

println(p1.x) # خروجی: 1.0
println(p1.y) # خروجی: 2.0

 

ساختارهای قابل تغییر (Mutable Structs):

به طور پیش‌فرض، `struct` ها تغییرناپذیر (immutable) هستند. برای ایجاد ساختارهای قابل تغییر، از کلمه کلیدی `mutable struct` استفاده کنید.

mutable struct Person
name::String
age::Int
end

person_mutable = Person("Alice", 30)
person_mutable.age = 31 # این تغییر مجاز است چون mutable است

 

کاربرد struct ها:

* مدل‌سازی اشیاء و مفاهیم پیچیده در دنیای واقعی.
* سازماندهی داده‌ها به روشی شیءگرا.
* تعریف متدها (methods) برای انواع داده‌های سفارشی.

 

5. انواع داده‌های نمادین (Symbol Type)

نمادها (Symbols) رشته‌های ثابت و منحصر به فردی هستند که معمولاً به عنوان کلید یا شناسه استفاده می‌شوند. آن‌ها در مقایسه با رشته‌ها کارآمدتر هستند زیرا تنها یک کپی از مقدار رشته در حافظه نگهداری می‌شود.

تعریف نماد: با استفاده از علامت `:`.

sym1 = :my_symbol
sym2 = :another_symbol

کاربرد نمادها:

* به عنوان کلید در دیکشنری‌ها (اگرچه رشته‌ها رایج‌ترند).
* در سیستم متادیتای جولیا.
* برای ارجاع به نام توابع یا متغیرها.

 

6. انواع داده‌های تابع (Function Type)

در جولیا، توابع نیز دارای نوع داده هستند. این امکان را می‌دهد که توابع را به عنوان آرگومان به توابع دیگر پاس داد یا آن‌ها را در ساختارهای داده ذخیره کرد.

نوع تابع:

my_function = sqrt # تابع جذر
println(typeof(my_function)) # خروجی: typeof(sqrt) (که یک نوع تابع است)

add_one(x) = x + 1
println(typeof(add_one)) # خروجی: typeof(add_one)

7. انواع داده‌های Null (Nothing Type)

نوع `Nothing` تنها یک مقدار دارد: `nothing`. این مقدار معمولاً نشان‌دهنده عدم وجود مقدار است.

استفاده از `nothing`:

result = nothing

8. انواع داده‌های نامعلوم (Union Types)

Union Types به شما اجازه می‌دهند تا مشخص کنید یک متغیر می‌تواند یکی از چندین نوع مختلف باشد. این امر انعطاف‌پذیری کد را افزایش می‌دهد.

 

تعریف Union Type:


<span style="font-family: Consolas, Monaco, monospace;"># متغیری که می‌تواند عدد صحیح یا رشته باشد</span>
<pre>x::Union{Int, String} = 10
x = "hello"
# x = 3.14 # این خط خطا ایجاد می‌کند

 

کاربرد Union Types:

*افزایش خوانایی و صراحت کد.

*کمک به کامپایلر برای بهینه‌سازی بهتر.

 

9. انواع داده‌های پارامتری (Parametric Types)

انواع داده‌های پارامتری به شما اجازه می‌دهند تا انواع داده‌ای تعریف کنید که بر اساس یک یا چند پارامتر دیگر ساخته می‌شوند. این مفهوم در انواع داده‌های ترکیبی مانند آرایه‌ها و ساختارها بسیار مهم است.

مثال آرایه پارامتری: `Vector{Int}` یک نوع پارامتری است که در آن `Vector` نوع پایه و `Int` پارامتر آن است. این نشان می‌دهد که این یک آرایه یک‌بعدی است که عناصر آن از نوع `Int` هستند.

تعریف struct پارامتری:

struct Pair{T1, T2}
first::T1
second::T2
end

p = Pair(1, "hello") # p::Pair{Int64, String}

 

 

سیستم انواع داده‌ای جولیا یکی از نقاط قوت کلیدی آن است که هم قدرت و هم انعطاف‌پذیری را برای طیف وسیعی از کاربردها فراهم می‌کند. از انواع داده‌های اولیه ساده گرفته تا ساختارهای پیچیده مانند آرایه‌ها، دیکشنری‌ها و ساختارهای سفارشی، جولیا ابزارهای لازم را برای نمایش دقیق و کارآمد داده‌ها در اختیار برنامه‌نویسان قرار می‌دهد. درک عمیق این مفاهیم نه تنها به نوشتن کدهای بهینه‌تر کمک می‌کند، بلکه پایه و اساس یادگیری مفاهیم پیشرفته‌تر در جولیا، مانند تعریف متدها، چندریختی (polymorphism) و برنامه‌نویسی جنریک (generic programming) را نیز فراهم می‌سازد. تسلط بر این انواع داده‌ها گامی اساسی برای هر کسی است که قصد دارد از پتانسیل کامل زبان برنامه‌نویسی جولیا بهره‌مند شود.



                            
error: