একক মান প্রসঙ্গে একাধিক মান


110

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

ধরা যাক আমার নিম্নলিখিত ফাংশন রয়েছে:

type Item struct {
   Value int
   Name string
}

func Get(value int) (Item, error) {
  // some code

  return item, nil
}

আমি কীভাবে item.Valueমার্জিতভাবে একটি নতুন ভেরিয়েবল বরাদ্দ করতে পারি । ত্রুটি পরিচালনার সাথে পরিচয় করানোর আগে, আমার ফাংশনটি স্রেফ ফিরে এসেছিল itemএবং আমি কেবল এটি করতে পারি:

val := Get(1).Value

এখন আমি এটি করি:

item, _ := Get(1)
val := item.Value

প্রথম ফিরে আসা ভেরিয়েবলটি সরাসরি অ্যাক্সেস করার কোনও উপায় নেই?


3
itemসাধারণত nilএকটি ত্রুটির ক্ষেত্রে হবে । প্রথমে ত্রুটি পরীক্ষা না করে আপনার কোডটি সে ক্ষেত্রে ক্র্যাশ হয়ে যাবে।
থমাস

উত্তর:


83

মাল্টি-ভ্যালু রিটার্ন ফাংশনের ক্ষেত্রে ফাংশনটি কল করার সময় আপনি ফলাফলের নির্দিষ্ট মানের ক্ষেত্রগুলি বা পদ্ধতিগুলি উল্লেখ করতে পারবেন না।

এবং যদি তাদের মধ্যে একটি হয় তবে errorএটি কোনও কারণের জন্য রয়েছে (যা ফাংশনটি ব্যর্থ হতে পারে) এবং আপনাকে এড়াতে হবে না কারণ যদি আপনি এটি করেন তবে আপনার পরবর্তী কোডটিও খারাপভাবে ব্যর্থ হতে পারে (যেমন রানটাইম আতঙ্কের ফলে) resulting

তবে এমন পরিস্থিতিতে থাকতে পারে যেখানে আপনি জানেন যে কোড কোনও পরিস্থিতিতে ব্যর্থ হবে না। এই ক্ষেত্রে আপনি একটি সহায়ক ফাংশন সরবরাহ করতে পারেন (বা পদ্ধতি) যা বাতিল করে দেবে error(বা যদি এখনও ঘটে তবে রানটাইম আতঙ্ক বাড়ায়)।
আপনি কোড থেকে কোনও ফাংশনের জন্য ইনপুট মান সরবরাহ করেন এবং আপনি জানেন যে তারা কাজ করে।
এই গ্রেট উদাহরণ templateএবং regexpপ্যাকেজ: আপনি কম্পাইল সময়ে একটি বৈধ টেমপ্লেট বা regexp প্রদান আপনি কি নিশ্চিতরূপে তারা সবসময় রানটাইম এ ত্রুটি ছাড়া পার্স করা যাবে হতে পারে। এই কারণে templateপ্যাকেজটি Must(t *Template, err error) *Templateফাংশন সরবরাহ করে এবং regexpপ্যাকেজটি MustCompile(str string) *Regexpফাংশন সরবরাহ করে : তারা ফিরে আসে নাerrorগুলি কারণ তাদের উদ্দেশ্যযুক্ত ব্যবহার যেখানে ইনপুটটি বৈধ হওয়ার গ্যারান্টিযুক্ত।

উদাহরণ:

// "text" is a valid template, parsing it will not fail
var t = template.Must(template.New("name").Parse("text"))

// `^[a-z]+\[[0-9]+\]$` is a valid regexp, always compiles
var validID = regexp.MustCompile(`^[a-z]+\[[0-9]+\]$`)

আপনার কেস ফিরে

যদি আপনি নিশ্চিত হতে পারেন তবে নির্দিষ্ট ইনপুট মানগুলির জন্য Get()উত্পাদিত হবে না error, আপনি এমন একটি সহায়তাকারী Must()ফাংশন তৈরি করতে পারেন যা তা ফেরত দেয় না errorতবে রানটাইম আতঙ্ক বাড়িয়ে দেয় যদি তা এখনও ঘটে:

func Must(i Item, err error) Item {
    if err != nil {
        panic(err)
    }
    return i
}

তবে আপনার সমস্ত ক্ষেত্রে এটি ব্যবহার করা উচিত নয়, যখন আপনি নিশ্চিত হন যে এটি সফল হয়। ব্যবহার:

val := Must(Get(1)).Value

বিকল্প / সরলীকরণ

এমনকি আপনি যদি Get()কলটিকে আপনার সহায়ক কার্যক্রমে অন্তর্ভুক্ত করেন তবে আপনি এটিকে আরও সরল করতে পারেন , আসুন এটি কল করুন MustGet:

func MustGet(value int) Item {
    i, err := Get(value)
    if err != nil {
        panic(err)
    }
    return i
}

ব্যবহার:

val := MustGet(1).Value

কিছু আকর্ষণীয় / সম্পর্কিত প্রশ্ন দেখুন:

গোলংয়ে একাধিক রিটার্ন কীভাবে পার্স করবেন

সাধারণ কার্যক্রমে গোলংয়ে 'ঠিক আছে' এর মতো মানচিত্র ফেরান


7

না, তবে এটি একটি ভাল জিনিস যেহেতু আপনার সর্বদা আপনার ত্রুটিগুলি পরিচালনা করা উচিত।

ত্রুটি পরিচালনা করা পিছিয়ে দেওয়ার জন্য এমন কৌশল রয়েছে যা আপনি ব্যবহার করতে পারেন, রব পাইকের ত্রুটিগুলি মান values

ew := &errWriter{w: fd}
ew.write(p0[a:b])
ew.write(p1[c:d])
ew.write(p2[e:f])
// and so on
if ew.err != nil {
    return ew.err
}

ব্লগ পোস্টের এই উদাহরণে তিনি চিত্রিত করেছেন যে আপনি কীভাবে এমন একটি errWriterপ্রকার তৈরি করতে পারেন যা আপনার কলিং শেষ না হওয়া পর্যন্ত ত্রুটি পরিচালনার পিছনে রয়েছে write


6

হ্যা এখানে.

অবাক, হাহ? আপনি একটি সাধারণ muteফাংশন ব্যবহার করে একাধিক রিটার্ন থেকে একটি নির্দিষ্ট মান পেতে পারেন :

package main

import "fmt"
import "strings"

func µ(a ...interface{}) []interface{} {
    return a
}

type A struct {
    B string
    C func()(string)
}

func main() {
    a := A {
        B:strings.TrimSpace(µ(E())[1].(string)),
        C:µ(G())[0].(func()(string)),
    }

    fmt.Printf ("%s says %s\n", a.B, a.C())
}

func E() (bool, string) {
    return false, "F"
}

func G() (func()(string), bool) {
    return func() string { return "Hello" }, true
}

https://play.golang.org/p/IwqmoKwVm-

আপনি কীভাবে মান স্লাইস / অ্যারে থেকে পছন্দ করে ঠিক তারপরে মান নম্বরটি কীভাবে নির্বাচন করবেন তা লক্ষ্য করুন এবং তারপরে আসল মান পেতে টাইপ করুন।

আপনি এই নিবন্ধ থেকে পিছনে বিজ্ঞান সম্পর্কে আরও পড়তে পারেন । লেখকের কাছে ক্রেডিট।


5

না, আপনি সরাসরি প্রথম মানটি অ্যাক্সেস করতে পারবেন না।

আমি মনে করি এটির জন্য একটি হ্যাক হ'ল "আইটেম" এবং "ত্রুটি" এর পরিবর্তে মানগুলির একটি অ্যারের ফিরিয়ে দেবে এবং তারপরে কেবল এটি item, _ := Get(1)[0] করবে তবে আমি এটির প্রস্তাব দিই না।


3

কিভাবে এই উপায়?

package main

import (
    "fmt"
    "errors"
)

type Item struct {
    Value int
    Name string
}

var items []Item = []Item{{Value:0, Name:"zero"}, 
                        {Value:1, Name:"one"}, 
                        {Value:2, Name:"two"}}

func main() {
    var err error
    v := Get(3, &err).Value
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(v)

}

func Get(value int, err *error) Item {
    if value > (len(items) - 1) {
        *err = errors.New("error")
        return Item{}
    } else {
        return items[value]
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.