গো শেল সনাক্তকরণ


165

শূন্য শনাক্ত করতে গো-তে আমি প্রচুর কোড দেখতে পাচ্ছি:

if err != nil { 
    // handle the error    
}

তবে, আমার এইরকম স্ট্রাক্ট রয়েছে:

type Config struct {
    host string  
    port float64
}

এবং কনফিগারেশন কনফিগারেশনের একটি উদাহরণ, যখন আমি করি:

if config == nil {
}

সংকলন ত্রুটি আছে, এই বলে: কনফিগার টাইপ করতে শূন্য রূপান্তর করতে পারে না


3
আমি বুঝতে পারি না কেন বন্দরটি ফ্লোট 64 টাইপ হয়?
আলামিন

2
এটা হওয়া উচিত নয়। গো-এর জেএসএন এপিআই জেএসওএন থেকে যে কোনও সংখ্যাকে ফ্লোট 64 এ আমদানি করে, আমাকে ফ্লোট 64 কে ইনটে রূপান্তর করতে হবে।
কিয়ান চেন

উত্তর:


179

সংকলকটি আপনাকে ত্রুটিটি নির্দেশ করছে, আপনি একটি কাঠামোর উদাহরণ এবং শূন্যতার তুলনা করছেন। এগুলি একই ধরণের নয় তাই এটি এটিকে একটি অবৈধ তুলনা হিসাবে বিবেচনা করে এবং আপনাকে চিত্কার করে।

আপনি এখানে যা করতে চান তা হ'ল আপনার কনফিগারেশন উদাহরণের সাথে একটি পয়েন্টারের তুলনা করা শূন্য করা, যা একটি বৈধ তুলনা। এটি করতে আপনি হয় গোলং নতুন অন্তর্নির্মিত ব্যবহার করতে পারেন , বা এটিতে একটি পয়েন্টার শুরু করতে পারেন:

config := new(Config) // not nil

অথবা

config := &Config{
                  host: "myhost.com", 
                  port: 22,
                 } // not nil

অথবা

var config *Config // nil

তারপরে আপনি যাচাই করতে সক্ষম হবেন

if config == nil {
    // then
}

5
আমার অনুমান var config &Config // nilহওয়া উচিত:var config *Config
টমাসজ প্লোনকা

var config *Configসঙ্গে ক্র্যাশ invalid memory address or nil pointer dereference। সম্ভবত আমাদের প্রয়োজনvar config Config
কাচর

আমি বুঝতে পারি যে এই পছন্দটির পিছনে যুক্তি আপনার নাও থাকতে পারে, তবে এটি আমার কাছে কোনও ধারণা দেয় না যে "যদি! (কনফিগার! = নীল)" বৈধ তবে "যদি কনফিগারেশন == নীল" হয় না। উভয়ই একই কাঠামো এবং নন-স্ট্রাক্টের মধ্যে তুলনা করছে।
retorquere

@ রিটার্কেরে তারা উভয়ই অবৈধ, play.golang.org/p/k2EmRcels6 দেখুন । এটি '! =' বা '==' তাতে কোনও পার্থক্য নেই; কনফিগার্ট স্ট্রাক্ট বা স্ট্রাক্টের পয়েন্টার কিনা তা পার্থক্য তৈরি করে।
স্টুবাসিক

আমি মনে করি এটি ভুল, কারণ এটি সর্বদা মিথ্যা: play.golang.org/p/g-MdbEbnyNx
Madeo

61

ওলিয়েড ছাড়াও, শূন্য মানগুলির উপর অনুমানটি দেখুন :

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

আপনি দেখতে পাচ্ছেন nilযে প্রতিটি ধরণের শূন্য মান নয় কেবল পয়েন্টার, ফাংশন, ইন্টারফেস, টুকরা, চ্যানেল এবং মানচিত্রের জন্য। এ কারণেই config == nilত্রুটি এবং &config == nilনা হওয়ার কারণ ।

কি না চেক করতে আপনার struct uninitialized আপনাকে তার নিজ নিজ শূন্য মান জন্য প্রতি সদস্য চেক করতে চাই (যেমন host == "", port == 0ইত্যাদি) বা একটি ব্যক্তিগত ক্ষেত্র যা একটি অভ্যন্তরীণ আরম্ভের পদ্ধতি দ্বারা সেট করা হয় না। উদাহরণ:

type Config struct {
    Host string  
    Port float64
    setup bool
}

func NewConfig(host string, port float64) *Config {
    return &Config{host, port, true}
}

func (c *Config) Initialized() bool { return c != nil && c.setup }

4
উপরের দিক থেকেও, সে কারণেই time.Timeএকটি IsZero()পদ্ধতি রয়েছে। তবে আপনার কাছে যেত না var t1 time.Time; if t1 == time.Time{}এবং আপনি পারে তেমনি কর if config == Config{}আপনার জন্য সব ক্ষেত্র দেখতে (struct হয় সমতা ভাল যান সংজ্ঞায়িত করা হয়)। তবে আপনার কাছে প্রচুর ক্ষেত্র থাকলে তা দক্ষ নয়। এবং, সম্ভবত শূন্য মানটি একটি বুদ্ধিমান এবং ব্যবহারযোগ্য মান তাই কোনওটির মধ্যে পাস করা বিশেষ নয়।
ডেভ সি

1
সূচিত ফাংশনটি ব্যর্থ হবে, যদি পয়েন্টার হিসাবে কনফিগার অ্যাক্সেস করা হয়। এটি রূপান্তরিত হতে পারেfunc (c *Config) Initialized() bool { return !(c == nil) }
সুন্দর

@ সুন্দর এই ক্ষেত্রে এটি করা সুবিধাজনক হতে পারে, তাই আমি পরিবর্তনটি প্রয়োগ করেছি। যাইহোক, সাধারণত আমি পদ্ধতি কলটির প্রাপ্তির শেষটি নিজেই নিল কিনা তা পরীক্ষা করার জন্য আশা করবো না, কারণ এটি কলারের কাজ হওয়া উচিত।
নেমো

16

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

package main

import "fmt"

type Config struct {
    host string
    port float64
}

func main() {
    //value
    var c1 Config
    c2 := Config{}
    c3 := *new(Config)

    //reference
    c4 := &Config{}
    c5 := new(Config)

    fmt.Println(&c1 == nil)
    fmt.Println(&c2 == nil)
    fmt.Println(&c3 == nil)
    fmt.Println(c4 == nil)
    fmt.Println(c5 == nil)

    fmt.Println(c1, c2, c3, c4, c5)
}

কোন ফলাফল:

false
false
false
false
false
{ 0} { 0} { 0} &{ 0} &{ 0}

6

আপনি যেমন চেক করতে পারেন struct_var == (struct{})। এটি আপনাকে শূন্যের সাথে তুলনা করতে দেয় না তবে এটি আরম্ভ করা হয়েছে কিনা তা তা পরীক্ষা করে না। এই পদ্ধতিটি ব্যবহার করার সময় সতর্কতা অবলম্বন করুন। আপনার স্ট্রাক্টের যদি এর ক্ষেত্রগুলির জন্য শূন্য মান থাকতে পারে তবে আপনার দুর্দান্ত সময় থাকবে না।

package main

import "fmt"

type A struct {
    Name string
}

func main() {
    a := A{"Hello"}
    var b A

    if a == (A{}) {
        fmt.Println("A is empty") // Does not print
    } 

    if b == (A{}) {
        fmt.Println("B is empty") // Prints
    } 
}

http://play.golang.org/p/RXcE06chxE


3

ভাষা বৈশিষ্ট উল্লেখ তুলনা অপারেটরদের 'আচরণে:

তুলনা অপারেটর

যে কোনও তুলনায়, প্রথম অপারেন্ড অবশ্যই দ্বিতীয় অপারেন্ড বা তার বিপরীতে টাইপের জন্য নির্ধারিত হবে।


Assignability

এর যে কোনও ক্ষেত্রে একটি মান x টাইপ টির ("x টি টির ক্ষেত্রে" এসযোগ্য হবে ") এর পরিবর্তনশীল হিসাবে নির্ধারিত হয়:

  • এক্স এর ধরণ টি এর সাথে সমান is
  • x এর ধরণ ভি এবং টি এর অন্তর্নিহিত ধরণের অভিন্ন ধরণের রয়েছে এবং কমপক্ষে ভি বা টি এর একটি নামযুক্ত প্রকার নয়।
  • টি একটি ইন্টারফেস টাইপ এবং এক্স প্রয়োগ করে টি।
  • এক্স একটি দ্বি নির্দেশমূলক চ্যানেল মান, টি একটি চ্যানেল প্রকার, এক্স এর ধরণ ভি এবং টি এর অভিন্ন উপাদান প্রকার এবং কমপক্ষে ভি বা টি এর একটি নামযুক্ত প্রকার নয়।
  • এক্স হল পূর্বনির্ধারিত শনাক্তকারী শূন্য এবং টি হল একটি পয়েন্টার, ফাংশন, স্লাইস, মানচিত্র, চ্যানেল বা ইন্টারফেস প্রকার।
  • টি টাইপ টি এর মান দ্বারা একটি টাইপযুক্ত ধ্রুবক প্রতিনিধিত্বযোগ্য x

0

Go 1.13 এবং তার পরে, আপনি প্যাকেজে Value.IsZeroপ্রদত্ত পদ্ধতিটি ব্যবহার করতে পারেন reflect

if reflect.ValueOf(v).IsZero() {
    // v is zero, do something
}

মৌলিক প্রকারগুলি ছাড়াও এটি অ্যারে, চ্যান, ফানক, ইন্টারফেস, মানচিত্র, পিটিআর, স্লাইস, অনিরাপদ পয়েন্টার এবং স্ট্রাক্টের জন্যও কাজ করে। দেখুন এই রেফারেন্সের জন্য।

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