ধনুর্বন্ধনী এবং বন্ধনীগুলির মধ্যে স্কালায় আনুষ্ঠানিক পার্থক্য কী এবং সেগুলি কখন ব্যবহার করা উচিত?


329

বন্ধনী ()এবং ধনুর্বন্ধনী মধ্যে ফাংশন আর্গুমেন্ট পাস মধ্যে আনুষ্ঠানিক পার্থক্য কি {}?

স্ক্যালার বইয়ের প্রোগ্রামিং থেকে আমার যে অনুভূতিটি পেয়েছে তা হ'ল স্কেলার বেশ নমনীয় এবং আমার সবচেয়ে ভাল লাগা উচিত তবে আমি দেখতে পেলাম যে কিছু ক্ষেত্রে সংকলন করা হয় অন্যরা না করে।

উদাহরণস্বরূপ (কেবল উদাহরণ হিসাবে বোঝানো; আমি এই বিশেষ উদাহরণটিই নয়, সাধারণ ক্ষেত্রে আলোচনা করা এমন কোনও প্রতিক্রিয়ার প্রশংসা করব):

val tupleList = List[(String, String)]()
val filtered = tupleList.takeWhile( case (s1, s2) => s1 == s2 )

=> ত্রুটি: সাধারণ অভিব্যক্তি অবৈধ শুরু

val filtered = tupleList.takeWhile{ case (s1, s2) => s1 == s2 }

=> ঠিক আছে।

উত্তর:


365

আমি এ সম্পর্কে একবার লেখার চেষ্টা করেছি, তবে নিয়মগুলি কিছুটা বিচ্ছিন্ন হওয়ায় আমি শেষ পর্যন্ত ছেড়ে দিয়েছি। মূলত, আপনাকে এটির হ্যাঙ্গ পেতে হবে।

সম্ভবত কোঁকড়া ধনুর্বন্ধনী এবং প্রথম বন্ধনী আন্তঃসত্তা ব্যবহার করা যেতে পারে যেখানে মনোনিবেশ করা ভাল: পদ্ধতি কলগুলিতে পরামিতিগুলি পাস করার সময়। আপনি কোঁকড়া ধনুর্বন্ধনী সঙ্গে বন্ধনী প্রতিস্থাপন করতে পারেন যদি এবং শুধুমাত্র যদি, পদ্ধতিটি একটি একক প্যারামিটার আশা করে। উদাহরণ স্বরূপ:

List(1, 2, 3).reduceLeft{_ + _} // valid, single Function2[Int,Int] parameter

List{1, 2, 3}.reduceLeft(_ + _) // invalid, A* vararg parameter

তবে এই নিয়মগুলি আরও ভালভাবে উপলব্ধি করার জন্য আপনাকে আরও জানতে হবে know

পেরেনগুলির সাথে সংকলন পরীক্ষা বৃদ্ধি করা

স্প্রেটির লেখকরা বৃত্তাকার প্যারেনগুলি সুপারিশ করেন কারণ তারা সংকলন পরীক্ষা বৃদ্ধি করেছেন। এটি স্প্রেয়ের মতো ডিএসএলদের জন্য বিশেষভাবে গুরুত্বপূর্ণ। পেরেন ব্যবহার করে আপনি সংকলককে বলছেন যে এটি কেবল একটি একক লাইন দেওয়া উচিত; অতএব আপনি যদি দুর্ঘটনাক্রমে দু'একটি বেশি দেন তবে এটি অভিযোগ করবে। এখন কোঁকড়া ধনুর্বন্ধনী সঙ্গে এটি হয় না - উদাহরণস্বরূপ আপনি যদি কোথাও কোনও অপারেটরকে ভুলে যান তবে আপনার কোডটি সংকলন করবে এবং আপনি অপ্রত্যাশিত ফলাফল এবং সন্ধানের জন্য খুব শক্ত একটি বাগ পেয়ে যাবেন। নীচে স্বীকৃতি দেওয়া হয়েছে (যেহেতু এক্সপ্রেশনগুলি খাঁটি এবং কমপক্ষে একটি সতর্কতা দেবে), তবে বিষয়টিটি উল্লেখ করে:

method {
  1 +
  2
  3
}

method(
  1 +
  2
  3
)

প্রথম সংকলন, দ্বিতীয়টি দেয় error: ')' expected but integer literal found। লেখক লিখতে চেয়েছিলেন 1 + 2 + 3

ডিফল্ট আর্গুমেন্টগুলির সাথে একাধিক-পরামিতি পদ্ধতির জন্য এটি একইরকম তর্ক করতে পারে; পেরেন ব্যবহার করার সময় দুর্ঘটনাক্রমে প্যারামিটারগুলি পৃথক করার জন্য কমাটি ভুলে যাওয়া অসম্ভব।

শব্দব্যবহার

ভার্বোসিটি সম্পর্কে একটি গুরুত্বপূর্ণ প্রায়শই উপেক্ষা করা নোট। কোঁকড়া ধনুর্বন্ধনী ব্যবহার অনিবার্যভাবে ভার্বোজ কোডের দিকে পরিচালিত করে যেহেতু স্কালা শৈলী গাইড স্পষ্টভাবে বলেছে যে বক্রাকার বন্ধনীগুলি বন্ধ করতে হবে তাদের নিজস্ব লাইনে:

… ফাংশনটির শেষ লাইনটি অবিলম্বে অনুসরণ করা বন্ধনী বন্ধনী তার নিজস্ব লাইনে রয়েছে।

অনেকগুলি স্ব-সংস্কারক, যেমন ইন্টেলিজজে, আপনার জন্য স্বয়ংক্রিয়ভাবে এই পুনর্নির্মাণটি সম্পাদন করবে। আপনি যখন পারেন তখন বৃত্তাকার প্যারেনগুলি ব্যবহার করার জন্য আটকে থাকার চেষ্টা করুন।

ইনফিক্স নোটেশন

ইনফিক্স স্বরলিপি ব্যবহার করার সময়, যেমন List(1,2,3) indexOf (2)একটি প্যারামিটার থাকে এবং আপনি যেমন লিখতে পারেন তবে প্যারেন্থিসিস বাদ দিতে পারেন List(1, 2, 3) indexOf 2। এটি বিন্দু-চিহ্নিতকরণের ঘটনা নয়।

এটিও নোট করুন যে যখন আপনার একক প্যারামিটারটি মাল্টি-টোকেন এক্সপ্রেশন থাকে, যেমন x + 2বা a => a % 2 == 0, আপনাকে এক্সপ্রেশনটির সীমানা নির্দেশ করার জন্য প্রথম বন্ধনী ব্যবহার করতে হয়।

tuples

কারণ আপনি মাঝে মাঝে বন্ধনীর হাতছাড়া করতে পারেন, কখনও কখনও একটি টিউপলের মতো বাড়ির প্রথম বন্ধনী প্রয়োজন হয় ((1, 2))এবং কখনও কখনও বাইরের প্রথম বন্ধনীও বাদ দেওয়া যেতে পারে, যেমন (1, 2)। এটি বিভ্রান্তির কারণ হতে পারে।

ফাংশন / আংশিক ফাংশন সহ case

স্কালা ফাংশন এবং আংশিক ফাংশন আক্ষরিক জন্য একটি সিনট্যাক্স আছে। দেখে মনে হচ্ছে:

{
    case pattern if guard => statements
    case pattern => statements
}

কেবলমাত্র অন্য জায়গাগুলি যেখানে আপনি caseবিবৃতি ব্যবহার করতে পারেন তা matchএবং catchকীওয়ার্ড সহ:

object match {
    case pattern if guard => statements
    case pattern => statements
}
try {
    block
} catch {
    case pattern if guard => statements
    case pattern => statements
} finally {
    block
}

আপনি caseঅন্য কোনও প্রসঙ্গে বিবৃতি ব্যবহার করতে পারবেন না । সুতরাং, আপনি ব্যবহার করতে চান তাহলে case, আপনি প্রয়োজন কোঁকড়া ধনুর্বন্ধনী। আপনি যদি ভাবছেন যে কোনও ফাংশন এবং আংশিক ফাংশনকে আক্ষরিক মধ্যে পার্থক্য কী করে, উত্তরটি হল: প্রসঙ্গ। যদি স্কালা কোনও ফাংশন প্রত্যাশা করে তবে একটি ফাংশন আপনি পাবেন। যদি এটি একটি আংশিক ফাংশন আশা করে, আপনি একটি আংশিক ফাংশন পাবেন। যদি উভয়ই প্রত্যাশিত হয় তবে এটি অস্পষ্টতা সম্পর্কে ত্রুটি দেয়।

এক্সপ্রেশন এবং ব্লক

পেরফেলেসিসকে subexpressions করতে ব্যবহার করা যেতে পারে। কোঁকড়া ধনুর্বন্ধনী কোডের ব্লক করতে ব্যবহার করা যেতে পারে (এই হল না একটি ফাংশন আক্ষরিক তাই এক মত ব্যবহার করার চেষ্টা হুঁশিয়ার)। কোডের একটি ব্লকে একাধিক বিবৃতি থাকে, যার মধ্যে প্রতিটি আমদানি বিবৃতি, একটি ঘোষণা বা একটি এক্সপ্রেশন হতে পারে। এটা এইভাবেই চলে:

{
    import stuff._
    statement ; // ; optional at the end of the line
    statement ; statement // not optional here
    var x = 0 // declaration
    while (x < 10) { x += 1 } // stuff
    (x % 5) + 1 // expression
}

( expression )

সুতরাং, আপনার যদি ঘোষণাপত্র, একাধিক বিবৃতি, এর importমতো বা অন্য কিছু দরকার হয় তবে আপনার কোঁকড়া ধনুর্বন্ধনী প্রয়োজন। এবং যেহেতু একটি অভিব্যক্তি একটি বিবৃতি, কোঁকড়া ধনুর্বন্ধনী এর ভিতরে প্রথম বন্ধনী প্রদর্শিত হতে পারে। তবে মজার বিষয় হ'ল কোডের ব্লকগুলিও হ'ল এক্সপ্রেশন, যাতে আপনি এটিকে একটি অভিব্যক্তির ভিতরে যে কোনও জায়গায় ব্যবহার করতে পারেন :

( { var x = 0; while (x < 10) { x += 1}; x } % 5) + 1

সুতরাং, যেহেতু এক্সপ্রেশনগুলি হ'ল বিবৃতি, এবং কোডগুলির ব্লকগুলি হল এক্সপ্রেশন, নীচের সমস্ত কিছুই বৈধ:

1       // literal
(1)     // expression
{1}     // block of code
({1})   // expression with a block of code
{(1)}   // block of code with an expression
({(1)}) // you get the drift...

যেখানে এগুলি বিনিময়যোগ্য নয়

মূলত, আপনি অন্য কোথাও এর {}সাথে ()বিপরীতে বা বিপরীত করতে পারবেন না । উদাহরণ স্বরূপ:

while (x < 10) { x += 1 }

এটি কোনও মেথড কল নয়, সুতরাং আপনি এটিকে অন্য কোনও উপায়ে লিখতে পারবেন না। ঠিক আছে, আপনি জন্য বন্ধনী ভিতরে কোঁকড়া ধনুর্বন্ধনী লাগাতে পারেন condition, পাশাপাশি কোড ব্লক করার জন্য কোঁকড়া ধনুর্বন্ধনী এর ভিতরে বন্ধনী ব্যবহার করতে পারেন :

while ({x < 10}) { (x += 1) }

সুতরাং, আমি আশা করি এটি সাহায্য করবে।


53
যে কারণে লোকেরা স্কালাকে জটিল বলে মনে করে। আমি নিজেকে একজন স্কালার উত্সাহী বলি।
andyczerwonka

আমার মনে হয় যে প্রতিটি পদ্ধতির জন্য স্কোপ কোডটি সহজ করে তোলে তার জন্য কোনও সুযোগের পরিচয় না দেওয়া! আদর্শভাবে কোনও পদ্ধতি ব্যবহার করা উচিত নয় {}- সবকিছুই একক শুদ্ধ অভিব্যক্তি হওয়া উচিত
samtहेest

1
@andyczerwonka আমি সম্পূর্ণরূপে একমত তবে এটি নমনীয়তা এবং অভিব্যক্তিপূর্ণ শক্তিটির জন্য আপনি যে প্রাকৃতিক এবং অনিবার্য মূল্য (?) প্রদান করেন তা => স্কালাকে অতিরিক্ত মূল্য দেওয়া হয় না। যেকোন নির্দিষ্ট পরিস্থিতির জন্য এটি সঠিক পছন্দ অবশ্যই অন্য বিষয়।
আশকান খ। নাজরী

হ্যালো, আপনি যখন List{1, 2, 3}.reduceLeft(_ + _)অবৈধ বলছেন , আপনার অর্থ কি এটির সিনট্যাক্স ভুল আছে? তবে আমি খুঁজে পাই যে কোডটি সংকলন করতে পারে। আমি আমার কোডটি এখানে
ক্যালভিন

আপনাকে ব্যবহৃত List(1, 2, 3)পরিবর্তে, সমস্ত উদাহরণ মধ্যে List{1, 2, 3}। হায়রে, স্কালার বর্তমান সংস্করণে (2.13), এটি একটি ভিন্ন ত্রুটি বার্তা (অপ্রত্যাশিত কমা) দিয়ে ব্যর্থ। সম্ভবত আসল ত্রুটিটি পেতে আপনাকে 2.7 বা 2.8 এ ফিরে যেতে হবে।
ড্যানিয়েল সি

56

এখানে বেশ কয়েকটি বিধিবিধান এবং সূচনা চলছে: প্রথমত, প্যারামিটার কোনও ফাংশন হলে স্কালা ব্রেসগুলি list.map(_ * 2)অনুমান করে , যেমন বন্ধনীগুলিতে অনুমিত হয়, এটি কেবল একটি সংক্ষিপ্ত রূপ list.map({_ * 2})। দ্বিতীয়ত, স্কালা আপনাকে শেষ প্যারামিটার তালিকার প্রথম বন্ধনী এড়িয়ে যাওয়ার অনুমতি দেয়, যদি সেই প্যারামিটার তালিকার একটি প্যারামিটার থাকে এবং এটি একটি ফাংশন হয়, সুতরাং (বা আপনি যদি অতিরিক্ত স্পষ্ট হতে চান) list.foldLeft(0)(_ + _)হিসাবে এটি লেখা যেতে পারে ।list.foldLeft(0) { _ + _ }list.foldLeft(0)({_ + _})

তবে, আপনি যদি যোগ করেন তবে caseযেমন অন্যরা উল্লেখ করেছেন, কোনও ফাংশনের পরিবর্তে একটি আংশিক ফাংশন পাবেন এবং স্কালা আংশিক ফাংশনগুলির জন্য বন্ধনীগুলি আবিষ্কার list.map(case x => x * 2)করবে না , সুতরাং কাজ করবে না list.map({case x => 2 * 2})এবং উভয়ই list.map { case x => x * 2 }করবে না।


4
শুধুমাত্র শেষ প্যারামিটার তালিকার নয়। উদাহরণস্বরূপ, list.foldLeft{0}{_+_}কাজ করে।
ড্যানিয়েল সি সোব্রাল

1
আহ, আমি নিশ্চিত যে আমি পড়েছি এটি কেবলমাত্র শেষ প্যারামিটারের তালিকা ছিল, তবে স্পষ্টতই আমি ভুল ছিলাম! জানা ভাল.
থিও

23

ধনুর্বন্ধনী এবং প্রথম বন্ধনী ব্যবহারের মানক করার জন্য সম্প্রদায়ের পক্ষ থেকে একটি প্রচেষ্টা রয়েছে, স্কালা স্টাইল গাইড (পৃষ্ঠা 21) দেখুন: http://www.codecommit.com/scala-style-guide.pdf

উচ্চতর অর্ডার পদ্ধতিগুলির কলগুলির জন্য প্রস্তাবিত বাক্য গঠনটি সর্বদা ব্রেস ব্যবহার করা এবং বিন্দুটি এড়ানো যায়:

val filtered = tupleList takeWhile { case (s1, s2) => s1 == s2 }

"সাধারণ" মেঠোড কলগুলির জন্য আপনার বিন্দু এবং প্রথম বন্ধনী ব্যবহার করা উচিত।

val result = myInstance.foo(5, "Hello")

18
আসলে কনভেনশনটি বৃত্তাকার ধনুর্বন্ধনী ব্যবহার করা হয়, সেই লিঙ্কটি আন-অফিসিয়াল। এটি কারণ কার্যকরী প্রোগ্রামিংয়ে সমস্ত ফাংশন কেবল নাগরিকদের অর্ডার করে এবং তাই অন্যরকম আচরণ করা উচিত নয়। দ্বিতীয়ত মার্টিন ওডারস্কি বলেছেন যে আপনাকে কেবল অপারেটরের জন্য পদ্ধতিগুলির (যেমন +, --) যেমন নিয়মিত পদ্ধতি নয় তেমন ইনফিক্স ব্যবহার করার চেষ্টা করা উচিত takeWhile। ইনফিক্স নোটেশনের পুরো বিষয়টি হ'ল ডিএসএল এবং কাস্টম অপারেটরদের মঞ্জুরি দেওয়া, অতএব এটির প্রসঙ্গে এটি সর্বদা ব্যবহার করা উচিত নয়।
সমবেত

17

আমি মনে করি না স্কালায় কোঁকড়ানো ধনুর্বন্ধনী সম্পর্কে বিশেষ বা জটিল কিছু আছে। এগুলি স্কালায় আপাত-জটিল ব্যবহারে দক্ষতা অর্জনের জন্য, কেবল কয়েকটি সাধারণ বিষয় মনে রাখবেন:

  1. কোঁকড়ানো বন্ধনীগুলি কোডের একটি ব্লক তৈরি করে, যা কোডের শেষ লাইনে মূল্যায়ন করে (প্রায় সমস্ত ভাষা এটি করে)
  2. কোডটি ব্লক করে আকাঙ্ক্ষিত হলে একটি ফাংশন তৈরি করা যায় (নিয়ম 1 অনুসরণ করে)
  3. কোঁকড়া ধনুর্বন্ধনী এক केस লাইন ব্যতীত এক-লাইন কোড জন্য বাদ দেওয়া যেতে পারে (স্কেলা পছন্দ)
  4. প্যারামিটার হিসাবে কোড ব্লকের সাথে ফাংশন কলগুলিতে বন্ধনীগুলি বাদ দেওয়া যেতে পারে (স্কেলার পছন্দ)

আসুন উপরের তিনটি নিয়ম অনুসারে কয়েকটি উদাহরণ ব্যাখ্যা করুন:

val tupleList = List[(String, String)]()
// doesn't compile, violates case clause requirement
val filtered = tupleList.takeWhile( case (s1, s2) => s1 == s2 ) 
// block of code as a partial function and parentheses omission,
// i.e. tupleList.takeWhile({ case (s1, s2) => s1 == s2 })
val filtered = tupleList.takeWhile{ case (s1, s2) => s1 == s2 }

// curly braces omission, i.e. List(1, 2, 3).reduceLeft({_+_})
List(1, 2, 3).reduceLeft(_+_)
// parentheses omission, i.e. List(1, 2, 3).reduceLeft({_+_})
List(1, 2, 3).reduceLeft{_+_}
// not both though it compiles, because meaning totally changes due to precedence
List(1, 2, 3).reduceLeft _+_ // res1: String => String = <function1>

// curly braces omission, i.e. List(1, 2, 3).foldLeft(0)({_ + _})
List(1, 2, 3).foldLeft(0)(_ + _)
// parentheses omission, i.e. List(1, 2, 3).foldLeft(0)({_ + _})
List(1, 2, 3).foldLeft(0){_ + _}
// block of code and parentheses omission
List(1, 2, 3).foldLeft {0} {_ + _}
// not both though it compiles, because meaning totally changes due to precedence
List(1, 2, 3).foldLeft(0) _ + _
// error: ';' expected but integer literal found.
List(1, 2, 3).foldLeft 0 (_ + _)

def foo(f: Int => Unit) = { println("Entering foo"); f(4) }
// block of code that just evaluates to a value of a function, and parentheses omission
// i.e. foo({ println("Hey"); x => println(x) })
foo { println("Hey"); x => println(x) }

// parentheses omission, i.e. f({x})
def f(x: Int): Int = f {x}
// error: missing arguments for method f
def f(x: Int): Int = f x

1. সমস্ত ভাষায় সত্য নয়। ৪. স্ক্যালায় আসলে সত্য নয়। যেমন: ডিফ এফ (এক্স: ইনট) = এফএক্স
এআইজি

@ আইজ, মন্তব্যের জন্য ধন্যবাদ। 1 এর জন্য, আমি সেই পরিচিতিটি পরামর্শ দিচ্ছিলাম যা স্কালা {}আচরণের জন্য সরবরাহ করে । আমি নির্ভুলতার জন্য শব্দটি আপডেট করেছি। এবং 4 এর জন্য ()এবং কাজের {}হিসাবে এবং এর মধ্যে মিথস্ক্রিয়াটির কারণে এটি কিছুটা জটিল and def f(x: Int): Int = f {x}:)
lcn

1
আমি স্ক্যালায় () এবং {mostly বেশিরভাগই বিনিময়যোগ্য হিসাবে ভাবতে চাই, এটি বাদে বিষয়বস্তুগুলি আলাদাভাবে পার্স করে। আমি সাধারণত f ({x}) লিখি না তাই f {x এতটা বন্ধনী বাদ দেওয়ার মতো মনে হয় না যতগুলি কোঁকড়ির সাথে প্রতিস্থাপন করে। অন্যান্য ভাষা আসলে আপনাকে পেরেথেসিগুলি বাদ দিতে দেয় না, উদাহরণস্বরূপ, এসএমএলে fun f(x) = f xবৈধ।
এআইজ

@ আইজ, তেমন আচরণ f {x}করা আমার পক্ষে f({x})আরও ভাল ব্যাখ্যা বলে মনে হয় , কারণ চিন্তাভাবনা ()এবং {}বিনিময়যোগ্য কম স্বজ্ঞাত। যাইহোক, f({x})ব্যাখ্যাটি কিছুটা স্কেল স্পেক দ্বারা সমর্থন করা হয়েছে (বিভাগ 6.6):ArgumentExprs ::= ‘(’ [Exprs] ‘)’ | ‘(’ [Exprs ‘,’] PostfixExpr ‘:’ ‘_’ ‘*’ ’)’ | [nl] BlockExp
lcn

13

আমি মনে করি এটি ফাংশন কলগুলিতে এবং কেন বিভিন্ন জিনিস ঘটে তাদের ব্যবহারগুলি ব্যাখ্যা করার মতো। যেহেতু কেউ ইতিমধ্যে বলেছিল কোঁকড়া ধনুর্বন্ধনী কোডের একটি ব্লক সংজ্ঞায়িত করে, এটিও একটি অভিব্যক্তি, তাই যেখানে অভিব্যক্তিটি প্রত্যাশিত হয় সেখানে সেট করা যায় এবং এটি মূল্যায়ন করা হবে। যখন মূল্যায়ন করা হয়, এর বিবৃতিগুলি কার্যকর করা হয় এবং শেষের বিবৃতি মানটি পুরো ব্লকের মূল্যায়নের ফলাফল (কিছুটা রুবির মতো)।

যে জিনিসটি আমরা যেমন করতে পারি তা হ'ল:

2 + { 3 }             // res: Int = 5
val x = { 4 }         // res: x: Int = 4
List({1},{2},{3})     // res: List[Int] = List(1,2,3)

শেষ উদাহরণটি কেবলমাত্র তিনটি পরামিতি সহ একটি ফাংশন কল, যার মধ্যে প্রতিটি প্রথমে মূল্যায়ন করা হয়।

ফাংশন কলগুলির সাথে এটি কীভাবে কাজ করে তা দেখতে এখন আসুন সহজ ফাংশনটি সংজ্ঞায়িত করি যা প্যারামিটার হিসাবে অন্য ফাংশন নেয়।

def foo(f: Int => Unit) = { println("Entering foo"); f(4) }

এটিকে কল করতে, আমাদের ফাংশনটি পাস করতে হবে যা ইনট টাইপের একটি প্যারাম নেয়, যাতে আমরা ফাংশনটি আক্ষরিক ব্যবহার করতে পারি এবং এটি ফু-এ দিতে পারি:

foo( x => println(x) )

এখন যেমন বলা হয়েছিল আগে আমরা একটি এক্সপ্রেশনের জায়গায় কোড ব্লক ব্যবহার করতে পারি তাই আসুন এটি ব্যবহার করুন

foo({ x => println(x) })

এখানে যা ঘটে তা হ'ল {inside এর মধ্যে কোডটি মূল্যায়ন করা হয় এবং ফাংশনটির মানটি ব্লক মূল্যায়নের মান হিসাবে ফিরে আসে, এই মানটি তখন foo এ দেওয়া হয়। এটি শব্দার্থগতভাবে পূর্ববর্তী কল হিসাবে একই।

তবে আমরা আরও কিছু যুক্ত করতে পারি:

foo({ println("Hey"); x => println(x) })

এখন আমাদের কোড ব্লকে দুটি স্টেটমেন্ট রয়েছে, এবং ফু ফুটানোর আগে এটির মূল্যায়ন করা হয়, তবে যা ঘটে তা প্রথম "আরে" মুদ্রিত হয়, তারপরে আমাদের ফাংশনটি ফু-তে প্রেরণ করা হয়, "এন্টারিং ফু" মুদ্রিত হয় এবং শেষ পর্যন্ত "4" মুদ্রিত হয় ।

যদিও এটি দেখতে কিছুটা কুৎসিত দেখাচ্ছে এবং স্কালা আমাদের এই ক্ষেত্রে প্রথম বন্ধনী এড়িয়ে যেতে দেয়, তাই আমরা লিখতে পারি:

foo { println("Hey"); x => println(x) }

অথবা

foo { x => println(x) }

এটি দেখতে দেখতে খুব সুন্দর এবং পূর্বেরগুলির সাথে সমান। এখানে এখনও কোডের ব্লকটি প্রথমে মূল্যায়ন করা হয় এবং মূল্যায়নের ফলাফল (যা x => প্রিন্টলান (এক্স)) ফু-এর যুক্তি হিসাবে পাস করা হয়।


1
এটা কি শুধু আমি। তবে আমি আসলে এর স্পষ্ট প্রকৃতি পছন্দ করি না foo({ x => println(x) })। হতে পারে আমি আমার পথে খুব আটকা
পড়েছি

7

যেহেতু আপনি ব্যবহার করছেন case, আপনি একটি আংশিক ফাংশন সংজ্ঞায়িত করছেন এবং আংশিক ফাংশনগুলির জন্য কোঁকড়া ধনুর্বন্ধনী প্রয়োজন।


1
আমি সাধারণভাবে একটি উত্তর চেয়েছি, এই উদাহরণের জন্য কেবল একটি উত্তর নয়।
মার্ক-

5

পেরেনগুলির সাথে সংকলন পরীক্ষা বৃদ্ধি করা

স্প্রে এর লেখকরা, সুপারিশ করেন যে বৃত্তাকার পেরেনগুলি বর্ধিত সংকলন পরীক্ষা করা উচিত। এটি স্প্রেয়ের মতো ডিএসএলদের জন্য বিশেষভাবে গুরুত্বপূর্ণ। পেরেন ব্যবহার করে আপনি সংকলককে বলছেন যে এটি কেবল একটি একক লাইন দেওয়া উচিত, অতএব আপনি যদি দুর্ঘটনাক্রমে দু'একটি বা তার বেশি প্রদান করেন তবে এটি অভিযোগ করবে। এখন কোঁকড়া ধনুর্বন্ধনী সঙ্গে এটি হয় না, উদাহরণস্বরূপ, আপনি একটি অপারেটর ভুলে যান কোথাও আপনার কোড সংকলিত হবে, আপনি অপ্রত্যাশিত ফলাফল এবং সম্ভাব্য একটি খুব হার্ড বাগ খুঁজে পেতে। নীচে স্বীকৃতি দেওয়া হয়েছে (যেহেতু এক্সপ্রেশনগুলি খাঁটি এবং কমপক্ষে একটি সতর্কতা দেবে), তবে বিষয়টি উল্লেখ করে

method {
  1 +
  2
  3
}

method(
  1 +
  2
  3
 )

প্রথম সংকলন, দ্বিতীয় দেয় error: ')' expected but integer literal found.লেখক লিখতে চেয়েছিলেন 1 + 2 + 3

ডিফল্ট আর্গুমেন্টগুলির সাথে একাধিক-পরামিতি পদ্ধতির জন্য এটি একইরকম তর্ক করতে পারে; পেরেন ব্যবহার করার সময় দুর্ঘটনাক্রমে প্যারামিটারগুলি পৃথক করার জন্য কমাটি ভুলে যাওয়া অসম্ভব।

শব্দব্যবহার

ভার্বোসিটি সম্পর্কে একটি গুরুত্বপূর্ণ প্রায়শই উপেক্ষা করা নোট। কোঁকড়া ধনুর্বন্ধনী ব্যবহার করা অনিবার্যভাবে ভার্বোজ কোডের দিকে পরিচালিত করে যেহেতু স্কাল স্টাইল গাইড স্পষ্টভাবে বলেছে যে বক্রাকার বন্ধনীগুলি বন্ধ করতে হবে তাদের নিজস্ব লাইনে: http://docs.scala-lang.org/style/declarations.html "... বন্ধনী বন্ধনী ফাংশনের শেষ লাইনটি অবিলম্বে তার নিজস্ব লাইনে রয়েছে is " অনেকগুলি স্ব-সংস্কারক, যেমন ইন্টেলিজের মতো, স্বয়ংক্রিয়ভাবে আপনার জন্য এই পুনর্নির্মাণটি সম্পাদন করবে। আপনি যখন পারেন তখন বৃত্তাকার প্যারেনগুলি ব্যবহার করার জন্য আটকে থাকার চেষ্টা করুন। উদাহরণস্বরূপ List(1, 2, 3).reduceLeft{_ + _}:

List(1, 2, 3).reduceLeft {
  _ + _
}

-2

ধনুর্বন্ধনী সহ, আপনি অর্ধিকোলন প্রেরণা পেয়েছেন আপনার জন্য এবং প্রথম বন্ধনী না। takeWhileফাংশনটি বিবেচনা করুন , যেহেতু এটি আংশিক কার্যকারিতা প্রত্যাশা করে, কেবলমাত্র {case xxx => ??? }কেস এক্সপ্রেশনের আশেপাশে প্রথম বন্ধনীর পরিবর্তে বৈধ সংজ্ঞা।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.