اس دستاویز کا مقصد ابتدائی Scala3 ڈویلپر کے لیے ہے جو پہلے سے ہی Scala نثر میں مہارت رکھتا ہے، لیکن تمام ` کے بارے میں حیران ہے۔implicits
` اور کوڈ میں پیرامیٹرائزڈ خصوصیات۔
یہ دستاویز وضاحت کرتی ہے کہ کیوں، کیسے، کہاں اور کب قسم کی کلاسز (TC).
اس دستاویز کو پڑھنے کے بعد ابتدائی Scala3 ڈویلپر استعمال کرنے کے لیے ٹھوس علم حاصل کرے گا اور اس کے ماخذ کوڈ میں ڈوب جائے گا۔ بہت زیادہ اسکیلا لائبریریوں کا اور محاوراتی اسکالا کوڈ لکھنا شروع کریں۔
آئیے اس کی وجہ سے شروع کرتے ہیں…
اظہار کا مسئلہ
1998 میں فلپ واڈلر نے کہا کہ "اظہار کا مسئلہ ایک پرانے مسئلے کا نیا نام ہے"۔ یہ سافٹ ویئر کی توسیع کا مسئلہ ہے۔ مسٹر واڈلر کی تحریر کے مطابق، اظہار کے مسئلے کے حل کے لیے درج ذیل اصولوں پر عمل کرنا ضروری ہے:
- اصول 1: کے نفاذ کی اجازت دیں۔ موجودہ طرز عمل (اسکالہ خصوصیت کے بارے میں سوچیں) جس پر لاگو کیا جائے۔ نئی نمائندگی (کیس کلاس کے بارے میں سوچو)
- اصول 2: کے نفاذ کی اجازت دیں۔ نئے طرز عمل پر لاگو کیا جائے موجودہ نمائندگی
- قاعدہ 3: اسے خطرے میں نہیں ڈالنا چاہئے۔ قسم کی حفاظت
- قاعدہ 4: اسے دوبارہ مرتب کرنے کی ضرورت نہیں ہونی چاہئے۔ موجودہ کوڈ
اس مسئلے کو حل کرنا اس مضمون کا چاندی کا دھاگہ ہوگا۔
اصول 1: نئی نمائندگی پر موجودہ طرز عمل کا نفاذ
کسی بھی آبجیکٹ پر مبنی زبان میں قاعدہ 1 کے ساتھ بیکڈ ان حل ہوتا ہے۔ ذیلی قسم پولیمورفزم. آپ محفوظ طریقے سے کسی بھی ` کو لاگو کر سکتے ہیںtrait
`` پر انحصار میں بیان کیا گیا ہے۔class
` آپ کے اپنے کوڈ میں، انحصار کو دوبارہ مرتب کیے بغیر۔ آئیے اسے عملی طور پر دیکھتے ہیں:
def todo = 42
type Height = Int
type Block = Int
object Lib1:
trait Blockchain:
def getBlock(height: Height): Block
case class Ethereum() extends Blockchain:
override def getBlock(height: Height) = todo
case class Bitcoin() extends Blockchain:
override def getBlock(height: Height) = todo
object Lib2:
import Lib1.*
case class Polkadot() extends Blockchain:
override def getBlock(height: Height): Block = todo
val eth = Lib1.Ethereum()
val btc = Lib1.Bitcoin()
val dot = Lib2.Polkadot()
اس فرضی مثال میں، لائبریری `Lib1
` (لائن 5) ایک خاصیت کی وضاحت کرتا ہے۔Blockchain
` (لائن 6) اس کے 2 نفاذ کے ساتھ (لائنز 9 اور 12)۔ `Lib1
` اس تمام دستاویز میں وہی رہے گا (قاعدہ 4 کا نفاذ)۔
`Lib2
` (لائن 15) موجودہ طرز عمل کو لاگو کرتی ہے۔Blockchain
ایک نئی کلاس پرPolkadot
` (قاعدہ 1) ایک قسم کے محفوظ (قاعدہ 3) طریقے سے، دوبارہ مرتب کیے بغیرLib1
` (قاعدہ 4)۔
قاعدہ 2: موجودہ نمائندگیوں پر لاگو ہونے والے نئے طرز عمل کا نفاذ
آئیے `میں تصور کریں۔Lib2
'ہم ایک نیا سلوک چاہتے ہیں'lastBlock
ہر ایک کے لیے خاص طور پر لاگو کیا جائے گا۔Blockchain
`.
پہلی چیز جو ذہن میں آتی ہے وہ پیرامیٹر کی قسم کی بنیاد پر ایک بڑا سوئچ بنانا ہے۔
def todo = 42
type Height = Int
type Block = Int
object Lib1:
trait Blockchain:
def getBlock(height: Height): Block
case class Ethereum() extends Blockchain:
override def getBlock(height: Height) = todo
case class Bitcoin() extends Blockchain:
override def getBlock(height: Height) = todo
object Lib2:
import Lib1.*
case class Polkadot() extends Blockchain:
override def getBlock(height: Height): Block = todo
def lastBlock(blockchain: Blockchain): Block = blockchain match
case _:Ethereum => todo
case _:Bitcoin => todo
case _:Polkadot => todo
object Lib3:
import Lib1.*
case class Polygon() extends Blockchain:
override def getBlock(height: Height): Block = todo
import Lib1.*, Lib2.*, Lib3.*
println(lastBlock(Bitcoin()))
println(lastBlock(Ethereum()))
println(lastBlock(Polkadot()))
println(lastBlock(Polygon()))
یہ حل قسم پر مبنی پولیمورفزم کا ایک کمزور دوبارہ نفاذ ہے جو پہلے ہی زبان میں پکا ہوا ہے!
`Lib1
` کو اچھوتا چھوڑ دیا گیا ہے (یاد رکھیں، اس دستاویز پر قاعدہ 4 نافذ کیا گیا ہے)۔
حل ` میں لاگو کیاLib2
` ہے ٹھیک ہے جب تک کہ ` میں ایک اور بلاکچین متعارف نہیں کرایا جاتاLib3
` یہ قسم کے حفاظتی اصول (قاعدہ 3) کی خلاف ورزی کرتا ہے کیونکہ یہ کوڈ لائن 37 پر رن ٹائم میں ناکام ہوجاتا ہے۔Lib2
` اصول 4 کی خلاف ورزی کرے گا۔
ایک اور حل ایک ` کا استعمال کر رہا ہے۔extension
`.
def todo = 42
type Height = Int
type Block = Int
object Lib1:
trait Blockchain:
def getBlock(height: Height): Block
case class Ethereum() extends Blockchain:
override def getBlock(height: Height) = todo
case class Bitcoin() extends Blockchain:
override def getBlock(height: Height) = todo
object Lib2:
import Lib1.*
case class Polkadot() extends Blockchain:
override def getBlock(height: Height): Block = todo
def lastBlock(): Block = todo
extension (eth: Ethereum) def lastBlock(): Block = todo
extension (btc: Bitcoin) def lastBlock(): Block = todo
import Lib1.*, Lib2.*
println(Bitcoin().lastBlock())
println(Ethereum().lastBlock())
println(Polkadot().lastBlock())
def polymorphic(blockchain: Blockchain) =
// blockchain.lastBlock()
???
`Lib1
` اچھوت چھوڑ دیا گیا ہے (پوری دستاویز میں قاعدہ 4 کا نفاذ)۔
`Lib2
` اس کی قسم (لائن 21) کے لئے رویے کی وضاحت کرتا ہے اور موجودہ اقسام (لائن 23 اور 25) کے لئے `ایکسٹینشن` کی وضاحت کرتا ہے۔
لائنز 28-30، نئے رویے کو ہر کلاس میں استعمال کیا جا سکتا ہے۔
لیکن اس نئے رویے کو پولیمورفیکل (لائن 32) کہنے کا کوئی طریقہ نہیں ہے۔ ایسا کرنے کی کوئی بھی کوشش تالیف کی غلطیوں (لائن 33) یا ٹائپ بیسڈ سوئچز کی طرف لے جاتی ہے۔
یہ اصول n°2 مشکل ہے۔ ہم نے اسے پولیمورفزم کی اپنی تعریف اور 'توسیع' چال کے ساتھ نافذ کرنے کی کوشش کی۔ اور یہ عجیب تھا۔
ایک گمشدہ ٹکڑا ہے جسے کہتے ہیں۔ ایڈہاک پولیمورفزم: ایک قسم کے مطابق رویے کے نفاذ کو محفوظ طریقے سے بھیجنے کی صلاحیت، جہاں بھی طرز عمل اور قسم کی تعریف کی گئی ہو۔ درج کریں۔ کلاس ٹائپ کریں۔ پیٹرن ہے
ٹائپ کلاس پیٹرن
ٹائپ کلاس (مختصر کے لیے TC) پیٹرن کی ترکیب میں 3 مراحل ہیں۔
- ایک نئے طرز عمل کی وضاحت کریں۔
- طرز عمل کو نافذ کریں۔
- طرز عمل کا استعمال کریں۔
مندرجہ ذیل حصے میں، میں TC پیٹرن کو انتہائی سیدھے طریقے سے لاگو کرتا ہوں۔ یہ لفظی، clunky اور ناقابل عمل ہے. لیکن ٹھہرو، وہ انتباہات کو دستاویز میں قدم بہ قدم طے کیا جائے گا۔
1. ایک نئے رویے کی وضاحت کریں۔
object Lib2:
import Lib1.*
trait LastBlock[A]:
def lastBlock(instance: A): Block
`Lib1
` ایک بار پھر، اچھوتا چھوڑ دیا گیا ہے۔
نیا سلوک is ٹی سی کو خصلت کے ذریعے عملی شکل دی گئی۔ خصوصیت میں بیان کردہ افعال اس طرز عمل کے کچھ پہلوؤں کو لاگو کرنے کا ایک طریقہ ہیں۔
پیرامیٹر `A
` اس قسم کی نمائندگی کرتا ہے جس پر ہم رویے کا اطلاق کرنا چاہتے ہیں، جو ` کی ذیلی قسمیں ہیں۔Blockchain
ہمارے معاملے میں۔
کچھ ریمارکس:
- اگر ضرورت ہو تو، پیرامیٹرائزڈ قسم `
A
` اسکالا قسم کے نظام کی طرف سے مزید محدود کیا جا سکتا ہے. مثال کے طور پر، ہم نافذ کر سکتے ہیں۔A
` ایک ` ہوناBlockchain
`. - اس کے علاوہ، TC میں اس میں اعلان کردہ اور بھی بہت سے افعال ہو سکتے ہیں۔
- آخر میں، ہر فنکشن میں کئی اور صوابدیدی پیرامیٹرز ہو سکتے ہیں۔
لیکن آئیے پڑھنے کی قابلیت کی خاطر چیزوں کو سادہ رکھیں۔
2. رویے کو نافذ کریں۔
object Lib2:
import Lib1.*
trait LastBlock[A]:
def lastBlock(instance: A): Block
val ethereumLastBlock = new LastBlock[Ethereum]:
def lastBlock(eth: Ethereum) = eth.lastBlock
val bitcoinLastBlock = new LastBlock[Bitcoin]:
def lastBlock(btc: Bitcoin) = http("http://bitcoin/last")
ہر قسم کے لیے نیا `LastBlock
رویے کی توقع ہے، اس رویے کی ایک خاص مثال موجود ہے۔
`Ethereum
` نفاذ لائن 22 کی گنتی ` سے کی جاتی ہے۔eth
` مثال پیرامیٹر کے طور پر منظور کی گئی۔
` کا نفاذLastBlock
'' کے لیے''Bitcoin
` لائن 25 ایک غیر منظم IO کے ساتھ لاگو کیا گیا ہے اور اس کا پیرامیٹر استعمال نہیں کرتا ہے۔
تو، `Lib2
'نئے رویے کو نافذ کرتا ہے'LastBlock
'' کے لیے''Lib1
` کلاسز
3. رویے کا استعمال کریں
object Lib2:
import Lib1.*
trait LastBlock[A]:
def lastBlock(instance: A): Block
val ethereumLastBlock = new LastBlock[Ethereum]:
def lastBlock(eth: Ethereum) = eth.lastBlock
val bitcoinLastBlock = new LastBlock[Bitcoin]:
def lastBlock(btc: Bitcoin) = http("http://bitcoin/last")
import Lib1.*, Lib2.*
def useLastBlock[A](instance: A, behavior: LastBlock[A]) =
behavior.lastBlock(instance)
println(useLastBlock(Ethereum(lastBlock = 2), ethereumLastBlock))
println(useLastBlock(Bitcoin(), bitcoinLastBlock))
لائن 30 `useLastBlock
`` کی مثال استعمال کرتا ہے۔A
` اور `LastBlock
اس مثال کے لیے رویے کی وضاحت کی گئی ہے۔
لائن 33 `useLastBlock
`` کی مثال کے ساتھ کہا جاتا ہے۔Ethereum
` اور ` کا نفاذLastBlock
`` میں بیان کیا گیا ہے۔Lib2
` نوٹ کریں کہ ` کے کسی بھی متبادل نفاذ کو پاس کرنا ممکن ہے۔LastBlock[A]
'' (سوچیں۔ انحصار انجکشن).
`useLastBlock
` نمائندگی (اصل A) اور اس کے رویے کے درمیان گلو ہے۔ ڈیٹا اور رویے کو الگ کر دیا گیا ہے، جس کے لیے فنکشنل پروگرامنگ کی وکالت کرتی ہے۔
بحث
آئیے اظہار کے مسئلے کے قواعد کو دوبارہ دیکھیں:
- اصول 1: کے نفاذ کی اجازت دیں۔ موجودہ طرز عمل پر لاگو کیا جائے نئی کلاسز
- اصول 2: کے نفاذ کی اجازت دیں۔ نئے طرز عمل پر لاگو کیا جائے موجودہ کلاسز
- قاعدہ 3: اسے خطرے میں نہیں ڈالنا چاہئے۔ قسم کی حفاظت
- قاعدہ 4: اسے دوبارہ مرتب کرنے کی ضرورت نہیں ہونی چاہئے۔ موجودہ کوڈ
اصول 1 کو ذیلی قسم کے پولیمورفزم کے ساتھ باکس سے باہر حل کیا جا سکتا ہے۔
ابھی پیش کردہ TC پیٹرن (پچھلا اسکرین شاٹ دیکھیں) اصول 2 کو حل کرتا ہے۔Lib1
` (قاعدہ 4)۔
تاہم کئی وجوہات کی بنا پر استعمال کرنا غیر عملی ہے:
- لائنز 33-34 ہمیں اس کی مثال کے ساتھ رویے کو واضح طور پر منتقل کرنا ہوگا۔ یہ ایک اضافی اوور ہیڈ ہے۔ ہمیں صرف لکھنا چاہئے۔
useLastBlock(Bitcoin())
`. - لائن 31 نحو غیر معمولی ہے۔ ہم اس کے بجائے ایک مختصر اور زیادہ آبجیکٹ پر مبنی لکھنے کو ترجیح دیں گے۔
instance.lastBlock()
بیان
آئیے TC کے عملی استعمال کے لیے اسکیلا کی کچھ خصوصیات کو اجاگر کرتے ہیں۔
بہتر ڈویلپر کا تجربہ
Scala میں خصوصیات اور مصنوعی شکروں کا ایک انوکھا مجموعہ ہے جو TC کو ڈویلپرز کے لیے واقعی ایک خوشگوار تجربہ بناتا ہے۔
مضمرات
مضمر دائرہ ایک خاص دائرہ کار ہے جسے مرتب کرنے کے وقت حل کیا جاتا ہے جہاں دی گئی قسم کی صرف ایک مثال موجود ہو سکتی ہے۔
ایک پروگرام ` کے ساتھ مضمر دائرہ کار میں ایک مثال رکھتا ہے۔given
` کلیدی لفظ متبادل طور پر ایک پروگرام مطلوبہ الفاظ کے ساتھ مضمر دائرہ کار سے ایک مثال بازیافت کرسکتا ہے۔using
`.
مضمر دائرہ کار مرتب وقت پر حل ہو جاتا ہے، رن ٹائم پر اسے متحرک طور پر تبدیل کرنے کا طریقہ معلوم ہوتا ہے۔ اگر پروگرام مرتب کرتا ہے تو، مضمر دائرہ کار حل ہوجاتا ہے۔ رن ٹائم کے وقت، یہ ممکن نہیں ہے کہ ان کا استعمال شدہ مضمرات غائب ہوں۔ غلط مضمر مثال کے استعمال سے صرف ممکنہ الجھن پیدا ہوسکتی ہے، لیکن یہ مسئلہ کرسی اور کی بورڈ کے درمیان مخلوق کے لیے چھوڑ دیا گیا ہے۔
یہ عالمی دائرہ کار سے مختلف ہے کیونکہ:
- اسے سیاق و سباق کے مطابق حل کیا گیا ہے۔ پروگرام کے دو مقامات مضمر دائرہ کار میں ایک ہی دی گئی قسم کی مثال استعمال کر سکتے ہیں، لیکن وہ دو مثالیں مختلف ہو سکتی ہیں۔
- منظر کے پیچھے کوڈ مضمر استدلال کے فنکشن کو اس وقت تک کام کرنے کے لیے پاس کر رہا ہے جب تک کہ مضمر استعمال نہ ہو جائے۔ یہ عالمی میموری کی جگہ استعمال نہیں کر رہا ہے۔
ٹائپ کلاس میں واپس جانا! آئیے بالکل وہی مثال لیتے ہیں۔
def todo = 42
type Height = Int
type Block = Int
def http(uri: String): Block = todo
object Lib1:
trait Blockchain:
def getBlock(height: Height): Block
case class Ethereum() extends Blockchain:
override def getBlock(height: Height) = todo
case class Bitcoin() extends Blockchain:
override def getBlock(height: Height) = todo
`Lib1
` وہی غیر ترمیم شدہ کوڈ ہے جو ہم نے پہلے بیان کیا تھا۔
object Lib2:
import Lib1.*
trait LastBlock[A]:
def lastBlock(instance: A): Block
given ethereumLastBlock:LastBlock[Ethereum] = new LastBlock[Ethereum]:
def lastBlock(eth: Ethereum) = eth.lastBlock
given bitcoinLastBlock:LastBlock[Bitcoin] = new LastBlock[Bitcoin]:
def lastBlock(btc: Bitcoin) = http("http://bitcoin/last")
import Lib1.*, Lib2.*
def useLastBlock[A](instance: A)(using behavior: LastBlock[A]) =
behavior.lastBlock(instance)
println(useLastBlock(Ethereum(lastBlock = 2)))
println(useLastBlock(Bitcoin()))
لائن 19 ایک نیا سلوک `LastBlock
` کی تعریف کی گئی ہے، بالکل اسی طرح جیسے ہم نے پہلے کیا تھا۔
لائن 22 اور لائن 25، `val
`` سے بدل دیا جاتا ہے۔given
` ` کے دونوں نفاذLastBlock
` مضمر دائرہ کار میں ڈالے جاتے ہیں۔
لائن 31 `useLastBlock
رویے کا اعلان کرتا ہے۔LastBlock
` ایک مضمر پیرامیٹر کے طور پر۔ مرتب کرنے والا ` کی مناسب مثال کو حل کرتا ہے۔LastBlock
` کال کرنے والے مقامات (لائنز 33 اور 34) سے سیاق و سباق کے مضمر دائرہ کار سے۔ لائن 28 ہر چیز کو ` سے درآمد کرتی ہے۔Lib2
`، مضمر دائرہ کار سمیت۔ لہذا، کمپائلر 22 اور 25 کی وضاحت کردہ مثالوں کو ` کے آخری پیرامیٹر کے طور پر پاس کرتا ہے۔useLastBlock
`.
لائبریری صارف کے طور پر، ٹائپ کلاس کا استعمال پہلے سے زیادہ آسان ہے۔ لائن 34 اور 35 ایک ڈویلپر کو صرف اس بات کو یقینی بنانا ہے کہ رویے کی ایک مثال مضمر دائرہ کار میں داخل کی گئی ہے (اور یہ محض `import
`)۔ اگر کوئی مضمر نہیں ہے `given
`جہاں کوڈ ہے`using
' یہ، مرتب کرنے والا اسے بتاتا ہے۔
اسکالا کا مضمر طور پر ان کے طرز عمل کی مثالوں کے ساتھ کلاس کے واقعات کو پاس کرنے کے کام کو آسان بناتا ہے۔
مضمر شکر
پچھلے کوڈ کی لائن 22 اور 25 کو مزید بہتر کیا جا سکتا ہے! آئیے ٹی سی کے نفاذ پر اعادہ کرتے ہیں۔
given LastBlock[Ethereum] = new LastBlock[Ethereum]:
def lastBlock(eth: Ethereum) = eth.lastBlock
given LastBlock[Bitcoin] = new LastBlock[Bitcoin]:
def lastBlock(btc: Bitcoin) = http("http://bitcoin/last")
لائنز 22 اور 25، اگر مثال کا نام غیر استعمال شدہ ہے، تو اسے ختم کیا جا سکتا ہے۔
given LastBlock[Ethereum] with
def lastBlock(eth: Ethereum) = eth.lastBlock
given LastBlock[Bitcoin] with
def lastBlock(btc: Bitcoin) = http("http://bitcoin/last")
لائنز 22 اور 25، قسم کی تکرار کو ` سے تبدیل کیا جا سکتا ہے۔with
` کلیدی لفظ
given LastBlock[Ethereum] = _.lastBlock
given LastBlock[Bitcoin] = _ => http("http://bitcoin/last")
چونکہ ہم اس میں ایک فنکشن کے ساتھ ایک انحطاط شدہ خصوصیت کا استعمال کرتے ہیں، IDE SAM اظہار کے ساتھ کوڈ کو آسان بنانے کا مشورہ دے سکتا ہے۔ اگرچہ درست ہے، مجھے نہیں لگتا کہ یہ SAM کا صحیح استعمال ہے، جب تک کہ آپ اتفاق سے گولفنگ کو کوڈ نہ کر لیں۔
اسکالا نحو کو ہموار کرنے کے لیے نحوی شکر پیش کرتا ہے، غیر ضروری نام دینے، اعلانیہ اور قسم کی فالتو پن کو ہٹاتا ہے۔
توسیع
سمجھداری سے استعمال کیا گیا، `extension
` میکانزم ٹائپ کلاس استعمال کرنے کے لیے نحو کو آسان بنا سکتا ہے۔
object Lib2:
import Lib1.*
trait LastBlock[A]:
def lastBlock(instance: A): Block
given LastBlock[Ethereum] with
def lastBlock(eth: Ethereum) = eth.lastBlock
given LastBlock[Bitcoin] with
def lastBlock(btc: Bitcoin) = http("http://bitcoin/last")
extension[A](instance: A)
def lastBlock(using tc: LastBlock[A]) = tc.lastBlock(instance)
import Lib1.*, Lib2.*
println(Ethereum(lastBlock = 2).lastBlock)
println(Bitcoin().lastBlock)
لائنز 28-29 ایک عام توسیع کا طریقہ `lastBlock
` کسی بھی ` کے لئے بیان کیا گیا ہے۔A
`ایک` کے ساتھLastBlock
` TC پیرامیٹر مضمر دائرہ کار میں۔
لائنز 33-34 ایکسٹینشن TC استعمال کرنے کے لیے ایک آبجیکٹ اورینٹڈ نحو کا فائدہ اٹھاتی ہے۔
object Lib2:
import Lib1.*
trait LastBlock[A]:
def lastBlock(instance: A): Block
given LastBlock[Ethereum] with
def lastBlock(eth: Ethereum) = eth.lastBlock
given LastBlock[Bitcoin] with
def lastBlock(btc: Bitcoin) = http("http://bitcoin/last")
extension[A](instance: A)(using tc: LastBlock[A])
def lastBlock = tc.lastBlock(instance)
def penultimateBlock = tc.lastBlock(instance) - 1
import Lib1.*, Lib2.*
val eth = Ethereum(lastBlock = 2)
println(eth.lastBlock)
println(eth.penultimateBlock)
val btc = Bitcoin()
println(btc.lastBlock)
println(btc.penultimateBlock)
سطر 28، TC پیرامیٹر کی وضاحت بھی پوری توسیع کے لیے کی جا سکتی ہے تاکہ تکرار سے بچا جا سکے۔ لائن 30 ہم ` کی وضاحت کے لیے ایکسٹینشن میں ٹی سی کو دوبارہ استعمال کرتے ہیں۔penultimateBlock
` (اگرچہ یہ ` پر لاگو کیا جا سکتا ہےLastBlock
` خصوصیت براہ راست)
جادو تب ہوتا ہے جب TC استعمال ہوتا ہے۔ اظہار بہت زیادہ قدرتی محسوس ہوتا ہے، اس رویے کو وہم دیتا ہے۔lastBlock
` مثال کے ساتھ ملا ہوا ہے۔
TC کے ساتھ عام قسم
import Lib1.*, Lib2.*
def useLastBlock1[A](instance: A)(using LastBlock[A]) = instance.lastBlock
def useLastBlock2[A: LastBlock](instance: A) = instance.lastBlock
val eth = Ethereum(lastBlock = 2)
assert(useLastBlock1(eth) == useLastBlock2(eth))
لائن 34 فنکشن ایک مضمر TC استعمال کرتا ہے۔ نوٹ کریں کہ اگر یہ نام غیر ضروری ہے تو TC کو نام دینے کی ضرورت نہیں ہے۔
TC پیٹرن اس قدر وسیع پیمانے پر استعمال کیا جاتا ہے کہ ایک عام قسم کا نحو موجود ہے جس میں "مضمون سلوک کے ساتھ ایک قسم" کا اظہار کیا جاتا ہے۔ سطر 36 نحو پچھلے ایک (لائن 34) کا زیادہ جامع متبادل ہے۔ یہ خاص طور پر بے نام مضمر TC پیرامیٹر کا اعلان کرنے سے گریز کرتا ہے۔
یہ ڈویلپر کے تجربے کے سیکشن کو ختم کرتا ہے۔ ہم نے دیکھا ہے کہ جب TC کا استعمال کیا جاتا ہے اور اس کی تعریف کی جاتی ہے تو ایکسٹینشنز، مضمرات اور کچھ نحوی چینی کس طرح کم بے ترتیبی والا نحو فراہم کر سکتے ہیں۔
خودکار اخذ
بہت ساری اسکیلا لائبریریاں TC کا استعمال کرتی ہیں، پروگرامر کو ان کے کوڈ بیس میں لاگو کرنے کے لیے چھوڑ دیتے ہیں۔
مثال کے طور پر سرس (ایک json ڈی سیریلائزیشن لائبریری) TC ` کا استعمال کرتا ہے۔Encoder[T]
` اور `Decoder[T]
پروگرامرز کو اپنے کوڈ بیس میں لاگو کرنے کے لیے۔ ایک بار لاگو ہونے کے بعد لائبریری کا پورا دائرہ کار استعمال کیا جا سکتا ہے۔
TC کے وہ نفاذ اکثر سے زیادہ ہوتے ہیں۔ ڈیٹا پر مبنی میپرز. انہیں کسی کاروباری منطق کی ضرورت نہیں ہے، لکھنے میں بورنگ ہیں، اور کیس کلاسز کے ساتھ ہم آہنگی برقرار رکھنے کے لیے ایک بوجھ ہے۔
ایسی صورت حال میں وہ کتب خانے پیش کرتے ہیں جسے کہتے ہیں۔ خود کار طریقے سے اخذ یا نیم خود کار طریقے سے اخذ مثال کے طور پر سرس کو دیکھیں خود کار طریقے سے اور نیم خود کار طریقے سے اخذ نیم خودکار اخذ کے ساتھ پروگرامر کچھ معمولی نحو کے ساتھ ایک قسم کی کلاس کی مثال کا اعلان کر سکتا ہے، جبکہ خودکار اخذ کرنے کے لیے درآمد کے علاوہ کسی کوڈ میں ترمیم کی ضرورت نہیں ہے۔
ہڈ کے نیچے، مرتب کرنے کے وقت، عام میکرو خود کا معائنہ کرتے ہیں۔ اقسام خالص ڈیٹا سٹرکچر کے طور پر اور لائبریری صارفین کے لیے TC[T] تیار کریں۔
عام طور پر TC حاصل کرنا بہت عام ہے، اس لیے Scala نے اس مقصد کے لیے ایک مکمل ٹول باکس متعارف کرایا۔ اس طریقہ کی ہمیشہ لائبریری دستاویزات کے ذریعہ تشہیر نہیں کی جاتی ہے حالانکہ یہ اخذ کرنے کا Scala 3 طریقہ ہے۔
object GenericLib:
trait Named[A]:
def blockchainName(instance: A): String
object Named:
import scala.deriving.*
inline final def derived[A](using inline m: Mirror.Of[A]): Named[A] =
val nameOfType: String = inline m match
case p: Mirror.ProductOf[A] => compiletime.constValue[p.MirroredLabel]
case _ => compiletime.error("Not a product")
new Named[A]:
override def blockchainName(instance: A):String = nameOfType.toLowerCase
extension[A] (instance: A)(using tc: Named[A])
def blockchainName = tc.blockchainName(instance)
import Lib1.*, GenericLib.*
case class Polkadot() derives Named
given Named[Bitcoin] = Named.derived
given Named[Ethereum] = Named.derived
println(Ethereum(lastBlock = 2).blockchainName)
println(Bitcoin().blockchainName)
println(Polkadot().blockchainName)
لائن 18 ایک نیا TC `Named
` متعارف کرایا گیا ہے۔ یہ TC سختی سے بات کرتے ہوئے بلاکچین کاروبار سے غیر متعلق ہے۔ اس کا مقصد کیس کلاس کے نام کی بنیاد پر بلاک چین کا نام رکھنا ہے۔
سب سے پہلے تعریف کی لائنوں 36-38 پر توجہ دیں۔ TC اخذ کرنے کے لیے 2 نحو ہیں:
- لائن 36 TC مثال کی براہ راست کیس کلاس پر ` کے ساتھ تعریف کی جا سکتی ہے۔
derives
` کلیدی لفظ ہڈ کے نیچے کمپائلر دیا ہوا ` تیار کرتا ہے۔Named
` مثال ` میںPolkadot
` ساتھی اعتراض. - لائن 37 اور 38، قسم کی کلاسز کی مثالیں پہلے سے موجود کلاسوں پر ` کے ساتھ دی جاتی ہیں
TC.derived
`
لائن 31 ایک عام توسیع کی وضاحت کی گئی ہے (پچھلے حصے دیکھیں) اور `blockchainName
' قدرتی طور پر استعمال کیا جاتا ہے.
`derives
` کلیدی لفظ فارم کے ساتھ ایک طریقہ کی توقع کرتا ہے `inline def derived[T](using Mirror.Of[T]): TC[T] = ???
` جس کی وضاحت لائن 24 ہے۔ میں اس کی گہرائی میں وضاحت نہیں کروں گا کہ کوڈ کیا کرتا ہے۔ وسیع خاکہ میں:
- `
inline def
` میکرو کی وضاحت کرتا ہے۔ - `
Mirror
` قسموں کا خود معائنہ کرنے کے لیے ٹول باکس کا حصہ ہے۔ مختلف قسم کے آئینے ہیں، اور لائن 26 پر کوڈ فوکس کرتا ہے `Product
` آئینہ (کیس کلاس ایک پروڈکٹ ہے)۔ لائن 27، اگر پروگرامرز کوئی ایسی چیز اخذ کرنے کی کوشش کرتے ہیں جو ` نہیں ہے۔Product
`، کوڈ مرتب نہیں ہوگا۔ - `
Mirror
` دوسری اقسام پر مشتمل ہے۔ ان میں سے ایک، `MirrorLabel
`، ایک سٹرنگ ہے جس میں قسم کا نام ہوتا ہے۔ اس قدر کو نفاذ میں استعمال کیا جاتا ہے، لائن 29، `Named
ٹی سی
TC مصنفین ایسے فنکشنز فراہم کرنے کے لیے میٹا پروگرامنگ کا استعمال کر سکتے ہیں جو عام طور پر ایک قسم کے دیے گئے TC کی مثالیں پیدا کرتے ہیں۔ پروگرامرز اپنے کوڈ کے لیے مثالیں بنانے کے لیے وقف لائبریری API یا Scala اخذ کرنے والے ٹولز کا استعمال کر سکتے ہیں۔
چاہے آپ کو TC لاگو کرنے کے لیے عام یا مخصوص کوڈ کی ضرورت ہو، ہر صورت حال کے لیے ایک حل موجود ہے۔
تمام فوائد کا خلاصہ
- یہ اظہار کا مسئلہ حل کرتا ہے۔
- نئی اقسام روایتی خصلت وراثت کے ذریعے موجودہ طرز عمل کو نافذ کر سکتی ہیں۔
- موجودہ اقسام پر نئے طرز عمل کو لاگو کیا جا سکتا ہے۔
- تشویش کی علیحدگی
- کوڈ گنگنا ہوا نہیں ہے اور آسانی سے ڈیلیٹ کیا جا سکتا ہے۔ ایک TC ڈیٹا اور رویے کو الگ کرتا ہے، جو کہ ایک فعال پروگرامنگ کا نعرہ ہے۔
- یہ محفوظ ہے
- یہ محفوظ قسم کی ہے کیونکہ یہ خود شناسی پر انحصار نہیں کرتا ہے۔ یہ قسموں پر مشتمل بڑے پیٹرن کے ملاپ سے گریز کرتا ہے۔ اگر آپ خود کو اس طرح کا کوڈ لکھتے ہوئے محسوس کرتے ہیں، تو آپ کو ایک ایسے کیس کا پتہ چل سکتا ہے جہاں TC پیٹرن بالکل موزوں ہوگا۔
- مضمر طریقہ کار مرتب محفوظ ہے! اگر کمپائل کے وقت کوئی مثال غائب ہے تو کوڈ مرتب نہیں ہوگا۔ رن ٹائم پر کوئی تعجب نہیں.
- یہ ایڈہاک پولیمورفزم لاتا ہے۔
- روایتی آبجیکٹ اورینٹڈ پروگرامنگ میں عام طور پر ایڈہاک پولیمورفزم غائب ہے۔
- ایڈہاک پولیمورفزم کے ساتھ، ڈویلپرز روایتی ذیلی ٹائپنگ کا استعمال کیے بغیر مختلف غیر متعلقہ اقسام کے لیے ایک ہی طرز عمل کو نافذ کر سکتے ہیں (جو کوڈ کو جوڑتا ہے)
- انحصار انجکشن آسان بنا دیا
- Liskov متبادل اصول کے سلسلے میں TC مثال کو تبدیل کیا جا سکتا ہے۔
- جب کسی جزو کا TC پر انحصار ہوتا ہے، تو ایک طنزیہ TC آسانی سے جانچ کے مقاصد کے لیے انجکشن لگایا جا سکتا ہے۔
جوابی اشارے
ہر ہتھوڑا مسائل کی ایک حد کے لئے ڈیزائن کیا گیا ہے.
قسم کی کلاسیں رویے کے مسائل کے لیے ہیں اور ڈیٹا وراثت کے لیے استعمال نہیں ہونا چاہیے۔ اس مقصد کے لیے ترکیب استعمال کریں۔
معمول کی ذیلی ٹائپنگ زیادہ سیدھی ہے۔ اگر آپ کوڈ بیس کے مالک ہیں اور آپ توسیع پذیری کا مقصد نہیں رکھتے ہیں، تو قسم کی کلاسیں حد سے زیادہ ہو سکتی ہیں۔
مثال کے طور پر، Scala کور میں، ایک ` ہے۔Numeric
` قسم کی کلاس:
trait Numeric[T] extends Ordering[T] {
def plus(x: T, y: T): T
def minus(x: T, y: T): T
def times(x: T, y: T): T
اس قسم کی کلاس کا استعمال کرنا واقعی سمجھ میں آتا ہے کیونکہ یہ نہ صرف اسکالا (Int, BigInt, …) میں سرایت شدہ اقسام پر الجبری الگورتھم کے دوبارہ استعمال کی اجازت دیتا ہے بلکہ صارف کی وضاحت شدہ اقسام پر بھی (a `ComplexNumber
مثال کے طور پر)۔
دوسری طرف، Scala مجموعہ کے نفاذ میں زیادہ تر ٹائپ کلاس کے بجائے ذیلی ٹائپنگ کا استعمال کیا جاتا ہے۔ یہ ڈیزائن کئی وجوہات کی بناء پر معنی رکھتا ہے:
- مجموعہ API کو مکمل اور مستحکم سمجھا جاتا ہے۔ یہ عمل درآمد سے وراثت میں ملنے والی خصلتوں کے ذریعے عام رویے کو بے نقاب کرتا ہے۔ انتہائی قابل توسیع ہونا یہاں کوئی خاص مقصد نہیں ہے۔
- اسے استعمال میں آسان ہونا چاہیے۔ TC اختتامی صارف پروگرامر پر ذہنی اوور ہیڈ کا اضافہ کرتا ہے۔
- TC کو کارکردگی میں چھوٹا اوور ہیڈ بھی لگ سکتا ہے۔ یہ مجموعہ API کے لیے اہم ہو سکتا ہے۔
- اگرچہ، مجموعہ API تیسرے فریق کی لائبریریوں کے ذریعے بیان کردہ نئے TC کے ذریعے اب بھی قابل توسیع ہے۔
نتیجہ
ہم نے دیکھا ہے کہ TC ایک سادہ نمونہ ہے جو ایک بڑا مسئلہ حل کرتا ہے۔ Scala امیر نحو کی بدولت، TC پیٹرن کو کئی طریقوں سے لاگو اور استعمال کیا جا سکتا ہے۔ ٹی سی پیٹرن فنکشنل پروگرامنگ پیراڈائم کے مطابق ہے اور صاف فن تعمیر کے لیے ایک شاندار ٹول ہے۔ کوئی سلور بلٹ نہیں ہے اور جب یہ فٹ ہو جائے تو TC پیٹرن کا اطلاق کرنا ضروری ہے۔
امید ہے کہ آپ نے اس دستاویز کو پڑھ کر علم حاصل کیا ہوگا۔
کوڈ پر دستیاب ہے۔ https://github.com/jprudent/type-class-article. اگر آپ کے پاس کسی قسم کے سوالات یا ریمارکس ہیں تو براہ کرم مجھ سے رابطہ کریں۔ اگر آپ چاہیں تو آپ ذخیرے میں مسائل یا کوڈ کے تبصرے استعمال کرسکتے ہیں۔
سافٹ ویئر انجنیئر
- SEO سے چلنے والا مواد اور PR کی تقسیم۔ آج ہی بڑھا دیں۔
- پلیٹو ڈیٹا ڈاٹ نیٹ ورک ورٹیکل جنریٹو اے آئی۔ اپنے آپ کو بااختیار بنائیں۔ یہاں تک رسائی حاصل کریں۔
- پلیٹوآئ اسٹریم۔ ویب 3 انٹیلی جنس۔ علم میں اضافہ۔ یہاں تک رسائی حاصل کریں۔
- پلیٹو ای ایس جی۔ کاربن، کلین ٹیک، توانائی ، ماحولیات، شمسی، ویسٹ مینجمنٹ یہاں تک رسائی حاصل کریں۔
- پلیٹو ہیلتھ۔ بائیوٹیک اینڈ کلینیکل ٹرائلز انٹیلی جنس۔ یہاں تک رسائی حاصل کریں۔
- ماخذ: https://www.ledger.com/blog/type-classes-in-scala3-a-beginners-guide
- : ہے
- : ہے
- : نہیں
- :کہاں
- ][p
- 1
- 10
- 11
- 12
- 14
- 15٪
- 19
- 1998
- 22
- 23
- 24
- 25
- 26٪
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 35٪
- 36
- 7
- 8
- 9
- a
- کی صلاحیت
- ہمارے بارے میں
- AC
- کے مطابق
- عمل
- اصل
- جوڑتا ہے
- وکالت
- پھر
- مقصد
- یلگوردمز
- تمام
- کی اجازت
- کی اجازت دیتا ہے
- ساتھ
- پہلے ہی
- بھی
- متبادل
- اگرچہ
- ہمیشہ
- an
- اور
- ایک اور
- کوئی بھی
- اے پی آئی
- اطلاقی
- کا اطلاق کریں
- مناسب
- فن تعمیر
- محفوظ شدہ دستاویزات
- کیا
- دلائل
- مضمون
- AS
- پہلوؤں
- At
- کرنے کی کوشش
- مصنفین
- خودکار
- دستیاب
- سے اجتناب
- واپس
- بیس
- کی بنیاد پر
- BE
- کیونکہ
- اس سے پہلے
- ابتدائی
- رویے
- رویے
- کیا جا رہا ہے
- کے درمیان
- بگ
- blockchain
- بورنگ
- دونوں
- باکس
- لاتا ہے
- وسیع
- BTC
- بوجھ
- کاروبار
- لیکن
- by
- فون
- کہا جاتا ہے
- کالر
- کر سکتے ہیں
- کیس
- چیئر
- تبدیل
- تبدیل کر دیا گیا
- طبقے
- کلاس
- صاف
- کوڈ
- کوڈ بیس
- کوڈ بیس
- مجموعہ
- مجموعے
- کس طرح
- آتا ہے
- تبصروں
- کامن
- ساتھی
- مکمل
- عمل
- جزو
- ساخت
- اندیشہ
- جامع
- اختتام
- الجھا ہوا
- الجھن
- پر مشتمل ہے
- کور
- درست
- سکتا ہے
- تخلیق
- تخلیق
- پرانی
- اہم
- اعداد و شمار
- ڈیٹا کی ساخت
- اعلان کرتا ہے
- وقف
- وضاحت
- کی وضاحت
- وضاحت کرتا ہے
- تعریف
- تعریفیں
- انحصار
- گہرائی
- اخذ کردہ
- ڈیزائن
- ڈیزائن
- کا پتہ لگانے کے
- ڈیولپر
- ڈویلپرز
- DID
- مختلف
- براہ راست
- ترسیل
- ڈوبکی
- do
- دستاویز
- کرتا
- نہیں کرتا
- نہیں
- متحرک طور پر
- ہر ایک
- کو کم
- آسان
- آسانی سے
- آسان
- ed
- ایمبیڈڈ
- آخر
- نافذ کریں
- نافذ کرنے والے
- آننددایک
- درج
- نقائص
- ETH
- بھی
- سب کچھ
- بالکل
- مثال کے طور پر
- اس کے علاوہ
- وجود
- موجودہ
- توقع
- امید ہے
- تجربہ
- وضاحت
- بیان کرتا ہے
- واضح طور پر
- ایکسپریس
- اظہار
- مدت ملازمت میں توسیع
- ملانے
- اضافی
- ناکام رہتا ہے
- خصوصیات
- محسوس ہوتا ہے
- مقرر
- توجہ مرکوز
- توجہ مرکوز
- کے بعد
- کے لئے
- فارم
- سے
- تقریب
- فنکشنل
- افعال
- مزید
- حاصل کرنا
- حاصل کی
- پیدا
- پیدا ہوتا ہے
- GitHub کے
- دی
- دے
- گلوبل
- عالمی دائرہ کار
- مقصد
- رہنمائی
- ہتوڑا
- ہاتھ
- ہوتا ہے
- ہے
- یہاں
- نمایاں کریں
- انتہائی
- اسے
- پکڑو
- ہڈ
- کس طرح
- HTML
- HTTP
- HTTPS
- i
- if
- برم
- تصور
- پر عملدرآمد
- نفاذ
- عمل درآمد
- عملدرآمد
- عمل
- درآمد
- درآمدات
- بہتر
- in
- سمیت
- وراثت
- مثال کے طور پر
- کے بجائے
- ارادہ
- میں
- متعارف
- شامل
- مسئلہ
- مسائل
- IT
- میں
- خطرے میں ڈالنا
- JSON
- صرف
- رکھیں
- جان
- علم
- زبان
- آخری
- لیڈز
- چھوڑ کر
- لیجر
- چھوڑ دیا
- کم
- لیتا ہے
- لائبریریوں
- لائبریری
- کی طرح
- لائن
- لائنوں
- لنکڈ
- مقامات
- منطق
- بہت
- میکرو
- بنا
- بنا دیا آسان
- ماجک
- برقرار رکھنے کے
- بنا
- بناتا ہے
- انداز
- بہت سے
- کے ملاپ
- مئی..
- me
- میکانزم
- یاد داشت
- ذہنی
- mers
- میٹا
- طریقہ
- شاید
- برا
- معمولی
- عکس
- لاپتہ
- زیادہ
- سب سے زیادہ
- زیادہ تر
- معیاری جملہ
- ضروری
- نام
- نامزد
- نام
- قدرتی
- ضرورت ہے
- ضرورت
- کبھی نہیں
- نئی
- نہیں
- براہ مہربانی نوٹ کریں
- اعتراض
- of
- پیش کرتے ہیں
- تجویز
- اکثر
- پرانا
- on
- ایک بار
- ایک
- صرف
- or
- دیگر
- ہمارے
- باہر
- خطوط
- پر
- خود
- پیرا میٹر
- پیرامیٹر
- پیرامیٹرز
- حصہ
- خاص طور پر
- پارٹی
- منظور
- منظور
- گزرتا ہے
- پاسنگ
- پاٹرن
- بالکل
- کارکردگی
- ٹکڑا
- پلاٹا
- افلاطون ڈیٹا انٹیلی جنس
- پلیٹو ڈیٹا
- مہربانی کرکے
- ممکن
- عملی
- کو ترجیح دیتے ہیں
- پیش
- پچھلا
- پہلے
- اصول
- مسئلہ
- مسائل
- مصنوعات
- پروگرام
- پروگرامر
- پروگرامر
- پروگرامنگ
- مناسب
- فراہم
- مقصد
- مقاصد
- ڈال
- رکھتا ہے
- سوالات
- رینج
- بلکہ
- تک پہنچنے
- پہنچ گئی
- پڑھنا
- واقعی
- وجہ
- ریپپ
- ہدایت
- انحصار کرو
- رہے
- یاد
- کو ہٹانے کے
- کی جگہ
- ذخیرہ
- نمائندگی
- کی نمائندگی کرتا ہے
- حل کیا
- احترام
- دوبارہ استعمال
- امیر
- حکمرانی
- قوانین
- رن ٹائم
- s
- محفوظ
- محفوظ طریقے سے
- سیفٹی
- خاطر
- سیم
- اسی
- منظر
- گنجائش
- سیکشن
- سیکشنز
- دیکھنا
- دیکھا
- احساس
- مقرر
- کئی
- مختصر
- ہونا چاہئے
- سلور
- سادہ
- آسان بنانے
- آسان بنانا
- ایک
- صورتحال
- چھوٹے
- So
- سافٹ ویئر کی
- ٹھوس
- حل
- حل کرتا ہے
- کچھ
- کچھ
- ماخذ
- ماخذ کوڈ
- خلا
- بات
- خصوصی
- مخصوص
- خاص طور پر
- مستحکم
- شروع کریں
- بیان
- مرحلہ
- مراحل
- ابھی تک
- براہ راست
- کارگر
- سلک
- ساخت
- اس طرح
- چینی
- مشورہ
- سوٹ
- سمجھا
- اس بات کا یقین
- حیرت
- سوئچ کریں
- ہم آہنگی
- نحو
- کے نظام
- لے لو
- ٹاسک
- بتاتا ہے
- ٹیسٹنگ
- سے
- شکریہ
- کہ
- ۔
- ماخذ
- ان
- ان
- وہاں.
- وہ
- بات
- چیزیں
- لگتا ہے کہ
- تھرڈ
- اس
- ان
- اگرچہ؟
- کے ذریعے
- وقت
- کرنے کے لئے
- کے آلے
- آلات
- اوزار
- چھوڑا
- روایتی
- کوشش کی
- واقعی
- کوشش
- دو
- قسم
- اقسام
- غیر معمولی
- کے تحت
- منفرد
- UNNAMED
- غیر ضروری
- جب تک
- اچھوت
- غیر استعمال شدہ
- صلی اللہ علیہ وسلم
- استعمال
- استعمال کی شرائط
- استعمال کیا جاتا ہے
- رکن کا
- صارفین
- استعمال
- کا استعمال کرتے ہوئے
- ہمیشہ کی طرح
- عام طور پر
- قیمت
- مختلف
- مہارت حاصل
- بہت
- چاہتے ہیں
- تھا
- راستہ..
- طریقوں
- we
- کمزور
- کیا
- کیا ہے
- جب
- جبکہ
- جس
- ڈبلیو
- پوری
- کیوں
- بڑے پیمانے پر
- گے
- عقلمندانہ
- ساتھ
- بغیر
- گا
- لکھنا
- تحریری طور پر
- غلط
- ابھی
- تم
- اور
- اپنے آپ کو
- زیفیرنیٹ