সি এর টেরিনারি অপারেটরের সমমর্যাদাপূর্ণ গো সমতুল্য কী?


295

সি / সি ++ (এবং সেই পরিবারের অনেক ভাষা) তে, একটি শর্তের উপর নির্ভর করে ভেরিয়েবলের ঘোষণা এবং প্রারম্ভিককরণের জন্য একটি সাধারণ বুদ্ধিমান, টার্নারি শর্তসাপেক্ষ অপারেটর ব্যবহার করে:

int index = val > 0 ? val : -val

গো শর্তসাপেক্ষ অপারেটর নেই। উপরের মত একই টুকরা কোডটি কার্যকর করার জন্য সবচেয়ে মূর্তিমান উপায় কী? আমি নিম্নলিখিত সমাধানে এসেছি, তবে এটি বেশ ভার্জোজ মনে হচ্ছে

var index int

if val > 0 {
    index = val
} else {
    index = -val
}

এর চেয়ে ভাল কিছু আছে কি?


আপনি অন্য অংশটি দিয়ে মানটি আরম্ভ করতে পারেন এবং শুধুমাত্র আপনার অবস্থা পরিবর্তনের জন্য পরীক্ষা করে দেখতে পারেন, এটি আরও ভাল হবে তা নিশ্চিত নয়
x29a

যেভাবে / তারপরে অনেকগুলি কেটে ফেলা উচিত ছিল। আমি 35 বছর আগে আমার প্রথম বেসিক প্রোগ্রামগুলি যে দিন লিখেছিলাম সেদিন থেকেই আমরা এটি করতাম। আপনার উদাহরণটি int index = -val + 2 * val * (val > 0);
হ'ল

8
@ হাই আপনার উদাহরণটি গো এর আইডিয়োমেটিক কোডের মতো পাঠযোগ্য বা টের্নারি অপারেটর ব্যবহার করে সি এর সংস্করণ হিসাবে অনেক দূরে। যাইহোক, এএফএইকি, গো তে এই সমাধানটি প্রয়োগ করা সম্ভব নয় কারণ একটি বুলিয়ান সংখ্যার মান হিসাবে ব্যবহার করা যায় না।
ফাবিয়েন

ভাবছেন কেন যান এমন কোনও অপারেটর সরবরাহ করেন না?
এরিক ওয়াং

@ এরিক ওয়াং দুটি কারণ, আফাইক: ১- আপনার এটির দরকার নেই এবং তারা ভাষাটি যতটা সম্ভব ছোট রাখতে চেয়েছিল। 2- এটি আপত্তিজনক বলে বোঝায়, অর্থাত্‍ সংশ্লেষিত একাধিক-লাইনের অভিব্যক্তিতে ব্যবহৃত হয় এবং ভাষা ডিজাইনাররা এটি পছন্দ করেন না।
ফাবিয়েন

উত্তর:


242

যেমন উল্লেখ করা হয়েছে (এবং আশাকরি আশঙ্কাজনকভাবে), গো-তে শর্তাবলীর কাজ করা if+elseহ'ল সত্যবাদী উপায়

var+if+elseকোডের সম্পূর্ণ প্রসারণ ব্লক ছাড়াও , এই বানানটি প্রায়শই ব্যবহৃত হয়:

index := val
if val <= 0 {
    index = -val
}

এবং যদি আপনার কাছে কোডের একটি ব্লক রয়েছে যা যথেষ্ট পরিমাণে পুনরাবৃত্তিযোগ্য, যেমন এর সমতুল্য int value = a <= b ? a : b, আপনি এটি ধরে রাখতে একটি ফাংশন তৈরি করতে পারেন:

func min(a, b int) int {
    if a <= b {
        return a
    }
    return b
}

...

value := min(a, b)

সংকলকটি এ জাতীয় সাধারণ ফাংশনগুলিকে ইনলাইন করবে, সুতরাং এটি দ্রুত, আরও স্পষ্ট এবং খাটো।


183
ওহে ছেলেরা, দেখো! আমি সবেমাত্র গোলাংগুলিতে টেরনারিটি অপারেটরকে পোর্ট করেছি! play.golang.org/p/ZgLwC_DHm0এত দক্ষ!

28
@ টমওয়াইল্ড আপনার সমাধানটি বেশ আকর্ষণীয় দেখায় তবে শর্তযুক্ত মূল্যায়ন - এর মধ্যে টার্নারি অপারেটরের অন্যতম প্রধান বৈশিষ্ট্য নেই।
ভ্লাদিমির মাত্তেভ

12
); @VladimirMatveev বন্ধ মান মোড়ানো
নিমো

55
c := (map[bool]int{true: a, false: a - 1})[a > b]আইএমএইচও-র উদ্বিগ্নতার উদাহরণ, এটি কাজ করেও।
রিক -777

34
তাহলে if/elseকথ্য পন্থা তারপর সম্ভবত Golang লেট বিবেচনা করতে পারে if/elseক্লজ কোন মান ফিরিয়ে: x = if a {1} else {0}। গো কোনওভাবেই এইভাবে কাজ করার একমাত্র ভাষা হবে না। একটি মূলধারার উদাহরণ স্কেলা। দেখুন: alvinalexander.com/scala/scala-ternary-operator-syntax
ম্যাক্স মারফি

80

না গোতে কোনও ত্রৈমাসিক অপারেটর নেই, যদি / অন্য বাক্য বিন্যাসটি মূ .়ভাবে ব্যবহৃত হয় using

কেন যান না ?: অপারেটর?

গো-তে কোনও ত্রৈমাসিক পরীক্ষার ব্যবস্থা নেই। আপনি একই ফলাফল অর্জন করতে নিম্নলিখিত ব্যবহার করতে পারেন:

if expr {
    n = trueVal
} else {
    n = falseVal
}

?:গো থেকে অনুপস্থিত থাকার কারণটি হ'ল ভাষার ডিজাইনাররা খুব সহজেই জটিল অভিব্যক্তি তৈরি করতে অপারেশনটি প্রায়শই ব্যবহার করে দেখেছিলেন। if-elseফর্ম, যদিও আর নিঃসন্দেহে পরিষ্কার হয়। একটি ভাষার জন্য কেবলমাত্র একটি শর্তসাপেক্ষ নিয়ন্ত্রণ প্রবাহের নির্মাণ প্রয়োজন।

- প্রায়শই জিজ্ঞাসিত প্রশ্নাবলী (FAQ) - গো প্রোগ্রামিং ভাষা


1
তাই কেবল ভাষা ডিজাইনাররা যা দেখেছেন, তাই তারা পুরো if-elseব্লকের জন্য ওয়ান-লাইনার বাদ দিয়েছে ? এবং কে বলে if-elseযে এইভাবে ব্যবহার করা হয় না? আমি আপনাকে আক্রমণ করছি না, আমি কেবল অনুভব করছি যে ডিজাইনারদের বাহানা যথেষ্ট বৈধ নয়
আলফ মোহ

58

ধরা যাক আপনার নিম্নোক্ত ত্রিভুজ প্রকাশ (সি তে):

int a = test ? 1 : 2;

গো-এ মুশকিল পদ্ধতিটি কেবল একটি ifব্লক ব্যবহার করা হবে :

var a int

if test {
  a = 1
} else {
  a = 2
}

তবে এটি আপনার প্রয়োজনীয়তার সাথে খাপ খায় না। আমার ক্ষেত্রে, কোড জেনারেশন টেম্পলেটটির জন্য আমার একটি ইনলাইন এক্সপ্রেশন দরকার।

আমি তাত্ক্ষণিকভাবে মূল্যায়িত বেনাম ফাংশনটি ব্যবহার করেছি:

a := func() int { if test { return 1 } else { return 2 } }()

এটি নিশ্চিত করে যে উভয় শাখার পাশাপাশি মূল্যায়ন করা হবে না।


জেনে রাখা ভাল যে ইনলাইনড আনন ফাংশনের কেবলমাত্র একটি শাখা মূল্যায়ন করে। তবে মনে রাখবেন যে এর মতো কেসগুলি সি এর টেরিনারি অপারেটরের সুযোগের বাইরে।
ওল্ফ

1
সি শর্তাধীন অভিব্যক্তি (সাধারণত তিন অপারেটর হিসাবে পরিচিত) তিন operands রয়েছে: expr1 ? expr2 : expr3। যদি expr1মূল্যায়ন করা হয় true, expr2মূল্যায়ন করা হয় এবং অভিব্যক্তির ফলাফল। অন্যথায়, expr3মূল্যায়ন করা হয় এবং ফলাফল হিসাবে সরবরাহ করা হয়। কেএন্ডআর দ্বারা এটি এএনএসআই সি প্রোগ্রামিং ভাষা বিভাগের ২.১১ অংশ থেকে এসেছে। আমার গো সমাধানটি এই নির্দিষ্ট শব্দার্থকে সংরক্ষণ করে। @ ওল্ফ আপনি কি পরামর্শ দিচ্ছেন তা কি আপনি পরিষ্কার করতে পারেন?
পিটার বায়ার

আমার মনে কী ছিল তা আমি নিশ্চিত নই, সম্ভবত অ্যান ফাংশনগুলি একটি সুযোগ (স্থানীয় নেমস্পেস) সরবরাহ করে যা সি / সি ++ এর টার্নারি অপারেটরের ক্ষেত্রে নয়। এই সুযোগ ব্যবহার করার জন্য
ওল্ফ

39

মানচিত্রের ত্রৈমাসিকটি প্রথম বন্ধনী ছাড়া পড়া সহজ:

c := map[bool]int{true: 1, false: 0} [5 > 4]

কেন এটি -২ পেয়েছে তা সম্পূর্ণরূপে নিশ্চিত নয় ... হ্যাঁ, এটি একটি কার্যক্রমে তবে এটি কাজ করে এবং টাইপ-নিরাপদ।
আলেসান্দ্রো শান্তিনি 11

30
হ্যাঁ, এটি কাজ করে, টাইপ-নিরাপদ, এবং এমনকি সৃজনশীল; তবে অন্যান্য মেট্রিক রয়েছে। টার্নারি অপসটি রানটাইমের সমতুল্য যদি / অন্যথায় হয় (উদাহরণস্বরূপ এই এস / ও পোস্টটি দেখুন )। এই প্রতিক্রিয়াটি নয় কারণ 1) উভয় শাখা কার্যকর করা হয়, 2) একটি মানচিত্র তৈরি করে 3) একটি হ্যাশ কল করে। এগুলি সবই "দ্রুত", তবে একটি / অন্যটি হিসাবে তত দ্রুত নয়। এছাড়াও, আমি যুক্তি দিয়ে বলব যে শর্ত {r = foo ()} অন্য {আর = বার () if
নাইট

অন্য ভাষাগুলিতে আমি এই পদ্ধতির ব্যবহার করি যখন আমার একাধিক ভেরিয়েবল থাকে এবং ক্লোজার বা ফাংশন পয়েন্টার বা জাম্প সহ। ভেরিয়েবলের সংখ্যা বৃদ্ধি পাওয়ায় নেস্টেড ifs লেখা ত্রুটি প্রবণ হয়ে ওঠে, যেমন {(0,0,0) => {কোড 1}, (0,0,1) => {কোড 2} ...} [(x> 1) , y> 1, z> 1)] ভেরিয়েবলের সংখ্যা বাড়ার সাথে সাথে (সিউডোকোড) আরও বেশি আকর্ষণীয় হয়ে ওঠে। বন্ধগুলি এই মডেলটিকে দ্রুত রাখে। আমি প্রত্যাশা করি যে একই ধরণের ট্রেড অফগুলি যেতে হবে।
ম্যাক্স মার্ফি

আমি মনে করি যেতে যেতে আপনি সেই মডেলের জন্য একটি স্যুইচ ব্যবহার করবেন। আমি মাঝে মাঝে অসুবিধে হলেও সুইচগুলি স্বয়ংক্রিয়ভাবে ভেঙে যেতে পছন্দ করি।
ম্যাক্স মরফি

8
যেমন ক্যাসি ফোয়েশ উল্লেখ করেছেন: simple and clear code is better than creative code.
ওল্ফ

11
func Ternary(statement bool, a, b interface{}) interface{} {
    if statement {
        return a
    }
    return b
}

func Abs(n int) int {
    return Ternary(n >= 0, n, -n).(int)
}

এটি অন্য কোনও ক্ষেত্রে ছাড়িয়ে যাবে না এবং যদি প্রয়োজন হয় তবে কাস্ট প্রয়োজন হয়। অবগতির জন্য:

বেঞ্চমার্কসঅবার্টনারি -8 100000000 18.8 এনএস / অপি

বেঞ্চমার্কএবিএসএফএলসি -8 2000000000 0.27 এনএস / ওপেন


এটিই সেরা সমাধান, সম্মিলন! একটি লাইন যা সমস্ত সম্ভাব্য কেসগুলি পরিচালনা করে
আলেকজান্দ্রো ডি অলিভিরা

2
আমি মনে করি না এটি শর্তযুক্ত মূল্যায়ন পরিচালনা করে, নাকি তা করে? পার্শ্ব-প্রতিক্রিয়া মুক্ত শাখাগুলির সাথে এটি গুরুত্বপূর্ণ নয় (যেমন আপনার উদাহরণ হিসাবে) তবে এটি যদি পার্শ্ব-প্রতিক্রিয়াযুক্ত এমন কিছু হয় তবে আপনি সমস্যার মধ্যে পড়ে যাবেন।
অ্যাশটন ওয়েয়ার্সডর্ফ

7

যদি আপনার সমস্ত শাখাগুলি পার্শ্ব প্রতিক্রিয়া তৈরি করে বা কম্পিউটেশনালি ব্যয়বহুল হয় তবে নিম্নলিখিতটি শব্দার্থ-সংরক্ষণের রিফ্যাক্টরিংয়ের জন্য হবে:

index := func() int {
    if val > 0 {
        return printPositiveAndReturn(val)
    } else {
        return slowlyReturn(-val)  // or slowlyNegate(val)
    }
}();  # exactly one branch will be evaluated

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

আপনি যদি নির্বিকারভাবে গুস্তাভোর পদ্ধতির প্রয়োগ করতে চান তবে নোট করুন :

    index := printPositiveAndReturn(val);
    if val <= 0 {
        index = slowlyReturn(-val);  // or slowlyNegate(val)
    }

আপনি একটি ভিন্ন আচরণ সহ একটি প্রোগ্রাম পেতে চাই ; val <= 0প্রোগ্রামটি যদি কোনও ধনাত্মক মান প্রিন্ট করে তবে এটি করা উচিত নয়! (আনুষাঙ্গিকভাবে, আপনি যদি শাখাগুলি বিপরীত করেন তবে আপনি অকারণে একটি ধীর ফাংশনটি কল করে ওভারহেডটি প্রবর্তন করবেন))


1
আকর্ষণীয় পড়ুন, তবে গুস্তাভোর পদ্ধতির আপনার সমালোচনা করার বিষয়টি আমি সত্যই বুঝতে পারছি না। আমি (ধরনের) দেখতে absমূল কোড (ভাল, আমি পরিবর্তন চাই ফাংশন <=থেকে <)। আপনার উদাহরণে আমি একটি সূচনা দেখতে পাচ্ছি, এটি কোনও ক্ষেত্রে বাড়াবাড়ি এবং বিস্তৃত হতে পারে। আপনি কি দয়া করে পরিষ্কার করতে পারেন: আপনার ধারণাটি আরও কিছুটা ব্যাখ্যা করুন?
ওল্ফ

মূল পার্থক্য হ'ল যে কোনও শাখার বাইরে কোনও ফাংশন কল করা তার শাখা গ্রহণ করা না হলেও পার্শ্ব প্রতিক্রিয়া তৈরি করবে । আমার ক্ষেত্রে, শুধুমাত্র ইতিবাচক সংখ্যাগুলি মুদ্রিত হবে কারণ ফাংশনটি printPositiveAndReturnকেবলমাত্র ইতিবাচক সংখ্যার জন্য ডাকা হয়। বিপরীতভাবে, সর্বদা একটি শাখা চালানো, তারপরে একটি ভিন্ন শাখাকে কার্যকর করার সাথে মানটিকে "ঠিক করা" প্রথম শাখার পার্শ্ব প্রতিক্রিয়াগুলি পূর্বাবস্থায় ফিরিয়ে দেয় না
eold

আমি দেখছি, তবে অভিজ্ঞ প্রোগ্রামাররা সাধারণত পার্শ্ব প্রতিক্রিয়া সম্পর্কে সচেতন হন। সেক্ষেত্রে আমি একটি এম্বেডড ফাংশনের সিসি ফয়েশের সুস্পষ্ট সমাধানটি পছন্দ করতাম , সংকলিত কোডটি একই রকম হলেও: এটি সংক্ষিপ্ত এবং বেশিরভাগ প্রোগ্রামারদের কাছে সুস্পষ্ট দেখাচ্ছে। আমি সত্যিই: আমাকে ভুল বুঝবেন না ভালবাসেন ); যান এর বন্ধ
উলফ

1
" অভিজ্ঞতা প্রোগ্রামাররা সাধারণত পার্শ্ব প্রতিক্রিয়া সম্পর্কে সচেতন হন " - নং শর্তাদির মূল্যায়ন এড়ানো একটি টার্নারি অপারেটরের অন্যতম প্রধান বৈশিষ্ট্য is
জোনাথন হার্টলি

6

পূর্বশব্দ: তর্ক ছাড়াই if elseএটি যাবার উপায়, আমরা এখনও ভাষা-সক্ষম কন্সট্রাক্টসগুলির সাথে খেলতে এবং আনন্দ পেতে পারি।

নিচের Ifকনস্ট্রাক্টটি আমার github.com/icza/goxলাইব্রেরিতে প্রচুর অন্যান্য পদ্ধতি সহ পাওয়া যায়, builtinx.Ifধরণের।


গো এমন কোনও আদিম প্রকার সহ যে কোনও ব্যবহারকারী-সংজ্ঞায়িত প্রকারের সাথে পদ্ধতিগুলি সংযুক্ত করার অনুমতি দেয় bool। আমরা boolএটির অন্তর্নিহিত ধরণের হিসাবে একটি কাস্টম টাইপ তৈরি করতে পারি এবং তারপরে শর্তে একটি সাধারণ ধরণের রূপান্তরকরণের সাথে আমরা এর পদ্ধতিতে অ্যাক্সেস পাই। অপারেন্ডগুলি থেকে প্রাপ্ত এবং নির্বাচন করা পদ্ধতি।

এটার মতো কিছু:

type If bool

func (c If) Int(a, b int) int {
    if c {
        return a
    }
    return b
}

আমরা কীভাবে এটি ব্যবহার করতে পারি?

i := If(condition).Int(val1, val2)  // Short variable declaration, i is of type int
     |-----------|  \
   type conversion   \---method call

উদাহরণস্বরূপ একটি বার্ষিক কাজ max():

i := If(a > b).Int(a, b)

একটি তিনটি কাজ abs():

i := If(a >= 0).Int(a, -a)

এটি দেখতে দুর্দান্ত, এটি সাধারণ, মার্জিত এবং দক্ষ (এটি ইনলাইনের জন্যও যোগ্য )।

"রিয়েল" টেরিনারি অপারেটরের সাথে তুলনা করে এক দিক: এটি সর্বদা সমস্ত অপারেশনকে মূল্যায়ন করে।

স্থগিত এবং কেবল-যদি-প্রয়োজন হয় মূল্যায়ন অর্জনের জন্য একমাত্র বিকল্প হ'ল ফাংশন (হয় ঘোষিত ফাংশন বা পদ্ধতি, বা ফাংশন আক্ষরিক ), যা কেবল যখন / যখন প্রয়োজন হয় তখন ডাকা হয়:

func (c If) Fint(fa, fb func() int) int {
    if c {
        return fa()
    }
    return fb()
}

এটি ব্যবহার করে: ধরে নেওয়া যাক আমাদের গণনা করার জন্য এই ফাংশনগুলি রয়েছে aএবং b:

func calca() int { return 3 }
func calcb() int { return 4 }

তারপর:

i := If(someCondition).Fint(calca, calcb)

উদাহরণস্বরূপ, শর্তটি বর্তমান বছর> 2020:

i := If(time.Now().Year() > 2020).Fint(calca, calcb)

আমরা যদি ফাংশন আক্ষরিক ব্যবহার করতে চাই:

i := If(time.Now().Year() > 2020).Fint(
    func() int { return 3 },
    func() int { return 4 },
)

চূড়ান্ত দ্রষ্টব্য: আপনার যদি স্বাক্ষরযুক্ত বিভিন্ন ফাংশন থাকে তবে আপনি সেগুলি এখানে ব্যবহার করতে পারবেন না। সেক্ষেত্রে আপনি এখনও প্রয়োগযোগ্য করে তুলতে ম্যাচের স্বাক্ষরের সাথে একটি ফাংশন আক্ষরিক ব্যবহার করতে পারেন।

উদাহরণস্বরূপ যদি calca()এবং এর calcb()খুব বেশি পরামিতি থাকে (রিটার্ন মান সহ)

func calca2(x int) int { return 3 }
func calcb2(x int) int { return 4 }

আপনি তাদের এইভাবে ব্যবহার করতে পারেন:

i := If(time.Now().Year() > 2020).Fint(
    func() int { return calca2(0) },
    func() int { return calcb2(0) },
)

গো খেলার মাঠে এই উদাহরণগুলি ব্যবহার করে দেখুন ।


4

oldশ্বরের উত্তর আকর্ষণীয় এবং সৃজনশীল, সম্ভবত চতুরও।

তবে এর পরিবর্তে এটি করার পরামর্শ দেওয়া হবে:

var index int
if val > 0 {
    index = printPositiveAndReturn(val)
} else {
    index = slowlyReturn(-val)  // or slowlyNegate(val)
}

হ্যাঁ, তারা উভয়ই মূলত একই সমাবেশে সংকলন করে, তবে এই কোডটি একটি বেনাম ফাংশনকে কল করার চেয়ে কেবলমাত্র একটি মান ফিরিয়ে দেওয়ার জন্য যা খুব সহজেই প্রথম স্থানে চলকটিতে লেখা যেতে পারে return

মূলত, সহজ এবং স্পষ্ট কোড সৃজনশীল কোডের চেয়ে ভাল।

অধিকন্তু, মানচিত্রের আক্ষরিক ব্যবহারের কোনও কোডই ভাল ধারণা নয়, কারণ মানচিত্রগুলি গো-তে মোটেও হালকা নয়। যেহেতু Go 1.3, ছোট মানচিত্রের জন্য এলোমেলো পুনরাবৃত্তি আদেশ নিশ্চিত করা হয়েছে এবং এটি কার্যকর করার জন্য, এটি ছোট মানচিত্রের জন্য বেশ কম দক্ষ স্মৃতি অনুসারে অর্জিত হয়েছে।

ফলস্বরূপ, অসংখ্য ছোট ছোট মানচিত্র তৈরি করা এবং অপসারণ করা উভয়ই স্থান গ্রহণ এবং সময়সাপেক্ষ। আমার কাছে একটি টুকরো কোড ছিল যা একটি ছোট মানচিত্র ব্যবহার করেছিল (দুটি বা তিনটি কী সম্ভবত রয়েছে, তবে সাধারণ ব্যবহারের ক্ষেত্রে কেবল একটি প্রবেশ ছিল) তবে কোডটি কুকুর ধীর ছিল। আমরা দ্বৈত স্লাইস কী [সূচক] => ডেটা [সূচীকরণ) মানচিত্র ব্যবহার করতে একই কোডটি পুনর্নির্মাণের চেয়ে কমপক্ষে কমপক্ষে 3 টি অর্ডারের কথা বলছি। এবং সম্ভবত আরও ছিল। কিছু ক্রিয়াকলাপ যা চালাতে কয়েক মিনিট সময় নিয়েছিল, তাই মিলি সেকেন্ডে সম্পূর্ণ করা শুরু করে \


1
simple and clear code is better than creative code- এটি আমার খুব পছন্দ, তবে আমি শেষ বিভাগে কিছুটা বিভ্রান্ত হয়ে যাচ্ছি dog slow, সম্ভবত এটি অন্যকেও বিভ্রান্ত করতে পারে?
ওল্ফ

1
সুতরাং, মূলত ... আমার কিছু কোড ছিল যা এক, দুটি, বা তিনটি এন্ট্রি দিয়ে ছোট মানচিত্র তৈরি করছিল, কিন্তু কোডটি খুব ধীরে চলছিল। সুতরাং, অনেকগুলি m := map[string]interface{} { a: 42, b: "stuff" }, এবং তারপরে অন্য ফাংশনটিতে এটি পুনরাবৃত্তি: for key, val := range m { code here } দুটি স্লাইস সিস্টেমে স্যুইচ করার পরে: keys = []string{ "a", "b" }, data = []interface{}{ 42, "stuff" }এবং তারপরে পুনরাবৃত্তি করুন যেমন for i, key := range keys { val := data[i] ; code here }জিনিসগুলি 1000 গুন বাড়িয়েছে।
ক্যাসি ফয়েশ

আমি স্পষ্টতার জন্য ধন্যবাদ। (সম্ভবত উত্তরটি এই সময়ে উন্নত হতে পারে could )
ওল্ফ

1
-.- ... স্পর্শ, যুক্তি ... স্পর্শ ... ... আমি শেষ পর্যন্ত তা পেয়ে যাব ...;)
Cey Foesch

3

ওয়ান-লাইনারগুলি যদিও নির্মাতারা এড়িয়ে চলেন না, তাদের জায়গা রয়েছে।

এইটি আপনাকে অলস মূল্যায়ন সমস্যার সমাধান করে optionচ্ছিকভাবে, প্রয়োজনে মূল্যায়নের জন্য ফাংশনগুলি পাস করে:

func FullTernary(e bool, a, b interface{}) interface{} {
    if e {
        if reflect.TypeOf(a).Kind() == reflect.Func {
            return a.(func() interface{})()
        }
        return a
    }
    if reflect.TypeOf(b).Kind() == reflect.Func {
        return b.(func() interface{})()
    }
    return b
}

func demo() {
    a := "hello"
    b := func() interface{} { return a + " world" }
    c := func() interface{} { return func() string { return "bye" } }
    fmt.Println(FullTernary(true, a, b).(string)) // cast shown, but not required
    fmt.Println(FullTernary(false, a, b))
    fmt.Println(FullTernary(true, b, a))
    fmt.Println(FullTernary(false, b, a))
    fmt.Println(FullTernary(true, c, nil).(func() string)())
}

আউটপুট

hello
hello world
hello world
hello
bye
  • interface{}অভ্যন্তরীণ castালাই ক্রিয়াকলাপটি সন্তুষ্ট করতে ফাংশনগুলিকে অবশ্যই ফিরে যেতে হবে ।
  • প্রসঙ্গের উপর নির্ভর করে আপনি একটি নির্দিষ্ট ধরণের আউটপুট কাস্ট করতে পছন্দ করতে পারেন।
  • আপনি যদি এ থেকে কোনও ফাংশন ফিরিয়ে দিতে চান তবে আপনাকে এটির মতো এটি মোড়ানো দরকার c

স্বতন্ত্র সমাধান এখানে আরো সুন্দর, কিন্তু কিছু ব্যবহারসমূহ তত স্পষ্ট হতে পারে।


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