দুটি স্ট্রাইক, টুকরো বা মানচিত্র সমান হলে কীভাবে তুলনা করবেন?


131

আমি দুটি স্ট্রাক, টুকরা এবং মানচিত্র সমান কিনা তা পরীক্ষা করতে চাই।

তবে আমি নিম্নলিখিত কোডটি নিয়ে সমস্যায় পড়ছি। প্রাসঙ্গিক লাইনে আমার মন্তব্য দেখুন।

package main

import (
    "fmt"
    "reflect"
)

type T struct {
    X int
    Y string
    Z []int
    M map[string]int
}

func main() {
    t1 := T{
        X: 1,
        Y: "lei",
        Z: []int{1, 2, 3},
        M: map[string]int{
            "a": 1,
            "b": 2,
        },
    }

    t2 := T{
        X: 1,
        Y: "lei",
        Z: []int{1, 2, 3},
        M: map[string]int{
            "a": 1,
            "b": 2,
        },
    }

    fmt.Println(t2 == t1)
    //error - invalid operation: t2 == t1 (struct containing []int cannot be compared)

    fmt.Println(reflect.ValueOf(t2) == reflect.ValueOf(t1))
    //false
    fmt.Println(reflect.TypeOf(t2) == reflect.TypeOf(t1))
    //true

    //Update: slice or map
    a1 := []int{1, 2, 3, 4}
    a2 := []int{1, 2, 3, 4}

    fmt.Println(a1 == a2)
    //invalid operation: a1 == a2 (slice can only be compared to nil)

    m1 := map[string]int{
        "a": 1,
        "b": 2,
    }
    m2 := map[string]int{
        "a": 1,
        "b": 2,
    }
    fmt.Println(m1 == m2)
    // m1 == m2 (map can only be compared to nil)
}

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


কনসাইডার এছাড়াও 'অবৈধ অপারেশন: t2 == t1 (মানচিত্র [স্ট্রিং] ইন্টিযুক্ত স্ট্রাক্টের তুলনা করা যায় না)', স্ট্রাক্টের তার সংজ্ঞার মধ্যে কোনও [int] অন্তর্ভুক্ত না থাকলে এটি ঘটে
ভিক্টর

উত্তর:


157

আপনি প্রতিবিম্ব ব্যবহার করতে পারেন। ডিপএকুয়াল , বা আপনি নিজের ফাংশনটি প্রয়োগ করতে পারেন (কোন পারফরম্যান্স ওয়াইজ প্রতিফলন ব্যবহারের চেয়ে ভাল হবে):

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

m1 := map[string]int{   
    "a":1,
    "b":2,
}
m2 := map[string]int{   
    "a":1,
    "b":2,
}
fmt.Println(reflect.DeepEqual(m1, m2))

69

reflect.DeepEqual আপনার প্রশ্নের মতো প্রায়শই দুটি স্ট্রকের মতো তুলনা করতে ভুলভাবে ব্যবহৃত হয়।

cmp.Equal স্ট্রাইক তুলনা করার জন্য একটি ভাল সরঞ্জাম।

প্রতিবিম্ব কেন খারাপ পরামর্শ দেওয়া হয় তা দেখতে, আসুন নথিটি দেখুন :

স্ট্রাক্ট মানগুলি গভীরভাবে সমান হয় যদি তাদের সম্পর্কিত ক্ষেত্রগুলি, উভয় রফতানি এবং অপ্রত্যাশিত, গভীরভাবে সমান হয়।

....

সংখ্যা, বুলস, স্ট্রিং এবং চ্যানেলগুলি - গো এর == অপারেটর ব্যবহার করে সমান হলে তারা গভীরভাবে সমান।

যদি আমরা time.Timeএকই ইউটিসি সময়ের দুটি মান তুলনা করি t1 == t2তবে তাদের মেটাডেটা টাইমজোন আলাদা হলে মিথ্যা হবে।

go-cmpজন্য দেখায় Equal()পদ্ধতি এবং যে সঠিকভাবে তুলনা বার ব্যবহার করে।

উদাহরণ:

m1 := map[string]int{
    "a": 1,
    "b": 2,
}
m2 := map[string]int{
    "a": 1,
    "b": 2,
}
fmt.Println(cmp.Equal(m1, m2)) // will result in true

9
হ্যাঁ অবশ্যই! পরীক্ষা লেখার সময়, এটি ব্যবহার করা খুব গুরুত্বপূর্ণ go-cmpএবং নাও reflect
কেভিন মাইনহার্ট

দুর্ভাগ্যক্রমে স্ট্রাক্টের পয়েন্টারগুলির একটি স্লাইসের সাথে কোনও কাঠামোর তুলনা করার জন্য প্রতিফলিত বা সিএমপি কাজ করে না। এটি এখনও পয়েন্টার একই হতে চায়।
ভায়োলামান

2
পুনঃটুইট করেছেন থেকে CMP ডকুমেন্টেশন : "যদি তারা বাতলান অন্তর্নিহিত মান এছাড়াও সমান হয় পয়েন্টার সমান"
Ilia Choly

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

17

আপনি এখানে কীভাবে নিজের ফাংশনটি রোল করবেন তা এখানে দেখুন http://play.golang.org/p/Qgw7XuLNhb

func compare(a, b T) bool {
  if &a == &b {
    return true
  }
  if a.X != b.X || a.Y != b.Y {
    return false
  }
  if len(a.Z) != len(b.Z) || len(a.M) != len(b.M) {
    return false
  }
  for i, v := range a.Z {
    if b.Z[i] != v {
      return false
    }
  }
  for k, v := range a.M {
    if b.M[k] != v {
      return false
    }
  }
  return true
}

3
আমি যোগ করার পরামর্শ দিচ্ছি if len(a.Z) != len(b.Z) || len(a.M) != len(b.M) { return false }, কারণ তাদের একটির অতিরিক্ত ক্ষেত্র থাকতে পারে।
ওয়ানঅফনে

সমস্ত কাঠামোগত তথ্য সংকলন সময়ে জানা। এটি লজ্জার বিষয় যে সংকলক কোনওভাবেই এই ভারী উত্তোলন করতে পারে না।
রিক -777

3
@ রিক-777 s স্লাইসগুলির জন্য কেবল তুলনা সংজ্ঞায়িত নেই। ভাষা ডিজাইনাররা এটি হতে চেয়েছিলেন। সাধারণ সংখ্যার তুলনা যেমন বলা যায় ঠিক তেমন সহজ নয়। যদি টুকরাগুলি একই ক্রমে একই উপাদান থাকে তবে কি সমান? কিন্তু যদি তাদের ক্ষমতা পৃথক হয়? ইত্যাদি
Justinas

1
যদি & a == & b true সত্য প্রত্যাবর্তন করে compare তুলনা করার প্যারামিটারগুলি মান দ্বারা পাস করা হয় তবে এটি কখনই সত্যের সাথে মূল্যায়ন করবে না।
শান

4

যেহেতু জুলাই 2017 আপনি ব্যবহার করতে পারেন cmp.Equalসঙ্গে cmpopts.IgnoreFieldsবিকল্প।

func TestPerson(t *testing.T) {
    type person struct {
        ID   int
        Name string
    }

    p1 := person{ID: 1, Name: "john doe"}
    p2 := person{ID: 2, Name: "john doe"}
    println(cmp.Equal(p1, p2))
    println(cmp.Equal(p1, p2, cmpopts.IgnoreFields(person{}, "ID")))

    // Prints:
    // false
    // true
}

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