Result Builder একটি Swift অ্যাট্রিবিউট যা @resultBuilder প্রোটোকলের মাধ্যমে বাস্তবায়িত হয় এবং এক্সপ্রেশনের একটি ক্রমকে একটি যৌগিক মানে রূপান্তরিত করে। কম্পাইলার কন্ট্রোল ফ্লো কনস্ট্রাক্ট if, for, switch সহ কোড ব্লকগুলিকে বিল্ডারের স্ট্যাটিক মেথড — buildBlock, buildEither, buildArray — কল করে। Swift Evolution প্রস্তাব SE-0289 (2022) অনুসারে, result builders বাহ্যিক পার্সার ছাড়াই Swift-এর ভিতরে ডিক্লারেটিভ DSL তৈরি করতে দেয়। সবচেয়ে পরিচিত উদাহরণ হল SwiftUI-তে @ViewBuilder, যেখানে ভিউ-এর বডি শর্তসাপেক্ষ এবং পৌনঃপুনিক উপাদান থেকে ডিক্লারেটিভ স্টাইলে নির্মিত হয়।
মূল বিষয়
TupleView-এ রূপান্তরিত করেif/else, switch, for-in সমর্থন করে মেথড buildOptional, buildEither, buildArray-এর মাধ্যমেResult Builder (পূর্বে function builders নামে পরিচিত) একটি Swift প্রক্রিয়া যা লাইন ব্রেক দ্বারা পৃথক করা এক্সপ্রেশনের একটি ক্রমকে একটি একক মানে পরিণত করতে দেয়। এটি @resultBuilder অ্যাট্রিবিউট ব্যবহার করে ঘোষিত হয় যা একটি স্ট্রাকচারে প্রয়োগ করা হয় যা স্ট্যাটিক রূপান্তর মেথড বাস্তবায়ন করে।
Result builders-এর আগে, SwiftUI body-র ডিক্লারেটিভ সিনট্যাক্স অসম্ভব ছিল। ভিউ-এর একটি কমপ্যাক্ট তালিকার পরিবর্তে, ডেভেলপারদের ম্যানুয়ালি TupleView কল লিখতে হত। Result Builder স্বয়ংক্রিয়ভাবে প্রতিটি এক্সপ্রেশন মোড়ায়, শাখাকরণ এবং লুপ সমর্থন করে, ডেভেলপারের কাছ থেকে কম্পোজিশনের জটিলতা লুকিয়ে রাখে।
Swift Evolution SE-0289 (2022-এ গৃহীত) অনুসারে, result builder হল function builders (SE-0258, Swift 5.1) ধারণার একটি বিবর্তন। মূল পরিবর্তন: @_functionBuilder থেকে @resultBuilder-এ নামকরণ এবং ফাংশন প্যারামিটারে সম্প্রসারণ, যা শুধু ভিউ বডি নয়, যেকোনো ক্লোজার আর্গুমেন্টের জন্য বিল্ডার ব্যবহার করতে দেয়।
Result builders ব্যবহার করুন যখন আপনার লাইব্রেরির ব্যবহারকারীদের জটিল কাঠামো তৈরি করার জন্য একটি ডিক্লারেটিভ সিনট্যাক্স প্রদানের প্রয়োজন হয় — কনফিগারেশন, কুয়েরি, UI কম্পোনেন্ট — ইম্পেরেটিভ অ্যাসেম্বলি কোড না লিখে।
Swift কম্পাইলার @resultBuilder দিয়ে চিহ্নিত প্রতিটি কোড ব্লককে বিল্ডারের স্ট্যাটিক মেথডের কলের ক্রমে রূপান্তরিত করে। আসুন একটি সাধারণ বিল্ডার দেখি যা স্ট্রিং সংযুক্ত করে:
@resultBuilder
struct StringBuilder {
static func buildBlock(_ parts: String...) -> String {
parts.joined(separator: " ")
}
}
এই বিল্ডার ব্যবহার — প্রতিটি স্ট্রিং একটি পৃথক লাইনে একটি স্পেস দিয়ে যুক্ত হয়:
@StringBuilder
func greeting() -> String {
"Hello"
"World"
"from"
"Swift"
}
// কম্পাইলার এটিকে রূপান্তরিত করে:
// StringBuilder.buildBlock("Hello", "World", "from", "Swift")
// ফলাফল: "Hello World from Swift"
কম্পাইলার ধারাবাহিক এক্সপ্রেশন গ্রুপ করে এবং সেগুলিকে buildBlock-এ ভেরিয়াডিক প্যারামিটার হিসেবে পাঠায়। যদি এক্সপ্রেশনের মধ্যে if আসে, কম্পাইলার শাখাকরণের জন্য buildOptional বা buildEither কল করে। for-in লুপের জন্য এটি buildArray কল করে। এইভাবে, সাধারণ Swift কোড কলের একটি চেইনে রূপান্তরিত হয় যা চূড়ান্ত মান নির্মাণ করে।
প্রতিটি result builder স্ট্যাটিক মেথডের একটি সেট সংজ্ঞায়িত করে যা কম্পাইলার রূপান্তরের সময় কল করে। প্রধান মেথডগুলি:
| মেথড | উদ্দেশ্য | কখন কল হয় |
|---|---|---|
| buildBlock | এক্সপ্রেশনের ক্রম একত্রিত করে | শাখাকরণ ছাড়া প্রতিটি ব্লকের জন্য |
| buildOptional | if ছাড়া else হ্যান্ডল করে | যখন if ছাড়া else থাকে |
| buildEither(first:) | if-else-এর প্রথম শাখা | if সহ else-এ |
| buildEither(second:) | if-else-এর দ্বিতীয় শাখা | if সহ else-এ |
| buildArray | for-in লুপ হ্যান্ডল করে | যখন for-in উপস্থিত থাকে |
| buildExpression | পৃথক এক্সপ্রেশন রূপান্তরিত করে | প্রতিটি এক্সপ্রেশনের জন্য buildBlock-এ পাঠানোর আগে |
| buildFinalResult | চূড়ান্ত রূপান্তর | ক্লোজার থেকে ফেরত আসার আগে |
সর্বনিম্ন বাস্তবায়নের জন্য শুধুমাত্র ভেরিয়াডিক প্যারামিটার সহ buildBlock প্রয়োজন — এটি শাখাকরণ ছাড়া ব্লকের জন্য যথেষ্ট। buildOptional এবং buildEither যোগ করলে শর্তসাপেক্ষ কাঠামোর সমর্থন অন্তর্ভুক্ত হয়, এবং buildArray লুপের জন্য। Swift ডকুমেন্টেশন (2025) অনুসারে, সর্বাধিক DSL নমনীয়তার জন্য সমস্ত মেথড বাস্তবায়নের সুপারিশ করা হয়।
buildExpression বিভিন্ন ধরনের এক্সপ্রেশন গ্রহণ করতে এবং সেগুলিকে একটি একক বিল্ডার টাইপে রূপান্তর করতে দেয়। উদাহরণস্বরূপ, @ViewBuilder-এ, buildExpression Text, Image, Button গ্রহণ করে এবং সেগুলিকে সাধারণ View টাইপে রূপান্তরিত করে।
আসুন HTML স্ট্রিং তৈরির জন্য একটি বিল্ডার তৈরির বিষয়ে বিবেচনা করি। এই DSL সরাসরি Swift-এ ডিক্লারেটিভ HTML লেখার অনুমতি দেবে:
@resultBuilder
enum HTMLBuilder {
static func buildBlock(_ components: String...) -> String {
components.joined()
}
static func buildOptional(_ component: String?) -> String {
component ?? ""
}
static func buildEither(first component: String) -> String {
component
}
static func buildEither(second component: String) -> String {
component
}
static func buildArray(_ components: [String]) -> String {
components.joined()
}
}
HTML জেনারেট করার জন্য কাস্টম বিল্ডার ব্যবহার:
func div(@HTMLBuilder _ content: () -> String) -> String {
"<div>\(content())</div>"
}
func p(_ text: String) -> String {
"<p>\(text)</p>"
}
let page = div {
p("Hello")
p("World")
if showFooter {
p("ফুটার")
}
}
// ফলাফল: <div><p>Hello</p><p>World</p><p>Footer</p></div>
Swift.org (2025)-এর “Building Custom Result Builders in Swift” নিবন্ধ অনুসারে, কাস্টম বিল্ডার লাইব্রেরিতে কনফিগারেশন ফাইল, UI কম্পোনেন্ট, ডেটা ম্যাপিং এবং এমনকি ডাটাবেস কুয়েরি তৈরির জন্য ব্যবহৃত হয় — যেখানেই শাখাকরণ সমর্থন সহ একটি ডিক্লারেটিভ সিনট্যাক্স প্রয়োজন।
@ViewBuilder হল SwiftUI-তে নির্মিত একটি result builder যা বেশিরভাগ কন্টেইনার ভিউ-এর content প্যারামিটারে প্রয়োগ করা হয়: VStack, HStack, ZStack, Group, List, এবং body প্রপার্টি নিজেই। এটি কমা বা র্যাপার ছাড়া পৃথক লাইনে একাধিক ভিউ লিখতে দেয়।
@ViewBuilder সমস্ত result builder মেথড বাস্তবায়ন করে, যার মধ্যে if-else, switch, এবং for-in-এর সমর্থন অন্তর্ভুক্ত। যখন একটি শর্ত সত্য হয়, buildEither(first:) একটি ভিউ ফেরত দেয়; যখন মিথ্যা, buildEither(second:) আরেকটি ফেরত দেয়। উভয় শাখাকে একই টাইপ ফেরত দিতে হবে, কিন্তু SwiftUI অভ্যন্তরীণভাবে AnyView বা ConditionalContent-এর মাধ্যমে টাইপ ইরেজার ব্যবহার করে।
struct GreetingView: View {
let isLoggedIn: Bool
var body: some View {
VStack {
Image(systemName: "person.circle")
Text("প্রোফাইল")
.font(.title)
if isLoggedIn {
Text("ফিরে আসায় স্বাগতম!")
.foregroundColor(.green)
} else {
Button("লগ ইন করুন") { }
}
}
}
}
@ViewBuilder ছাড়া, একই কোডের জন্য প্রতিটি শর্তসাপেক্ষ অংশের জন্য Group বা AnyView ব্যবহারের প্রয়োজন হত, যা কর্মক্ষমতা নষ্ট করে। @ViewBuilder স্বয়ংক্রিয়ভাবে প্রতিটি সংমিশ্রণের জন্য সবচেয়ে কার্যকর উপস্থাপনা — ConditionalContent বা TupleView — নির্বাচন করে।
প্রথম সীমাবদ্ধতা হল buildBlock-এ সর্বাধিক এক্সপ্রেশন সংখ্যা। Swift স্ট্যান্ডার্ড লাইব্রেরি 2–10টি এক্সপ্রেশনের জন্য buildBlock ওভারলোড সংজ্ঞায়িত করে। যদি একটি ব্লকে 10টির বেশি এক্সপ্রেশন থাকে, কম্পাইলার একটি ত্রুটি তৈরি করবে। সমাধান — উপ-ব্লকে বিভক্ত করতে Group বা VStack-এর মাধ্যমে গ্রুপিং।
দ্বিতীয় সীমাবদ্ধতা হল বিল্ডার ব্লকের ভিতরে ভেরিয়েবল এবং অ্যাসাইনমেন্টের সমর্থনের অভাব। @ViewBuilder-এর ভিতরে let x = 5 ঘোষণা করা যায় না। সমস্ত এক্সপ্রেশন অবশ্যই এমন এক্সপ্রেশন হতে হবে যা বিল্ডার টাইপের একটি মান ফেরত দেয়। মধ্যবর্তী গণনার জন্য, বিল্ডারের বাইরে গণনা বা বিভিন্ন টাইপের সমর্থন সহ buildExpression ব্যবহার করুন।
তৃতীয় সীমাবদ্ধতা হল ডিবাগিং জটিলতা। Result builder-এর ভিতরে কম্পাইলেশন ত্রুটি প্রায়ই বিভ্রান্তিকর বার্তা দেয়, বিশেষ করে যখন if/else শাখায় টাইপ মেলে না। ডিবাগিংয়ের জন্য স্পষ্ট রিটার্ন টাইপ এবং AnyView ব্যবহার করুন, যদিও পরেরটি কর্মক্ষমতা হ্রাস করে। Hacking with Swift (2025) অনুসারে, ব্যবহারিক টিপ — শাখাকরণ ছাড়া একটি সাধারণ বিল্ডার দিয়ে শুরু করুন এবং ধীরে ধীরে শর্তসাপেক্ষ কাঠামোর সমর্থন যোগ করুন।
প্রায়শই জিজ্ঞাসিত প্রশ্ন
Result Builder একটি Swift অ্যাট্রিবিউট যা স্ট্যাটিক মেথডের মাধ্যমে এক্সপ্রেশনের ক্রমকে একটি ফলাফল মানে রূপান্তরিত করে। এটি ডিক্লারেটিভ DSL তৈরি করতে দেয়, সবচেয়ে পরিচিত উদাহরণ হল @ViewBuilder SwiftUI-তে ইম্পেরেটিভ কোড ছাড়া ভিউ হায়ারার্কি তৈরির জন্য।
@resultBuilder অ্যাট্রিবিউট সহ একটি স্ট্রাকচার ঘোষণা করুন এবং কমপক্ষে buildBlock মেথড বাস্তবায়ন করুন। শর্তের জন্য buildOptional এবং buildEither যোগ করুন; লুপের জন্য buildArray যোগ করুন। একটি ফাংশনে ক্লোজার প্যারামিটারের আগে বিল্ডার অ্যাট্রিবিউট ব্যবহার করুন।
শুধুমাত্র buildBlock বাধ্যতামূলক। অন্যান্য সমস্ত মেথড — buildOptional, buildEither, buildArray, buildExpression, buildFinalResult — ঐচ্ছিক এবং সংশ্লিষ্ট কাঠামোর সমর্থন যোগ করে। যত বেশি মেথড বাস্তবায়িত হয়, DSL তত নমনীয় হয়।
@ViewBuilder হল View প্রোটোকলের জন্য result builder-এর একটি কংক্রিট বাস্তবায়ন। এটি SwiftUI-তে @resultBuilder অ্যাট্রিবিউট সহ একটি স্ট্রাকচার হিসাবে সংজ্ঞায়িত, যা বিভিন্ন সংখ্যক ভিউ (TupleView)-এর জন্য buildBlock মেথড, ConditionalContent-এর জন্য buildEither এবং ForEach-এর জন্য buildArray প্রদান করে।
হ্যাঁ, স্ট্যান্ডার্ড buildBlock ওভারলোড 10টি এক্সপ্রেশন পর্যন্ত সমর্থন করে। এর বেশি হলে, উপ-ব্লকে বিভক্ত করতে নেস্টেড কন্টেইনার (Group, VStack) ব্যবহার করুন। একটি কাস্টম বিল্ডার সীমা ছাড়া একটি ভেরিয়াডিক buildBlock সংজ্ঞায়িত করতে পারে।
সারসংক্ষেপ
buildBlock, buildEither, buildOptional, buildArray-এর কল দিয়ে প্রতিস্থাপন করেআমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন