আমি কীভাবে আক্ষরিক * int64 করব?


112

আমার *int64ক্ষেত্রের সাথে স্ট্রাক্ট টাইপ রয়েছে ।

type SomeType struct {
    SomeField *int64
}

আমার কোডের এক পর্যায়ে, আমি এটির আক্ষরিক ঘোষণা করতে চাই (বলুন, যখন আমি জানলাম মানটি 0 হওয়া উচিত, বা 0 এর দিকে নির্দেশ করা, আপনি আমার অর্থ কী তা জানেন)

instance := SomeType{
    SomeField: &0,
}

... বাদে এটি কাজ করে না

./main.go:xx: cannot use &0 (type *int) as type *int64 in field value

সুতরাং আমি এই চেষ্টা

instance := SomeType{
    SomeField: &int64(0),
}

... তবে এটিও কাজ করে না

./main.go:xx: cannot take the address of int64(0)

আমি এটা কিভাবে করবো? প্লেসহোল্ডার ভেরিয়েবল ব্যবহার করা একমাত্র সমাধান আমি নিয়ে আসতে পারি

var placeholder int64
placeholder = 0

instance := SomeType{
    SomeField: &placeholder,
}

নোট: &0সিনট্যাক্স কাজ করে জরিমানা যখন এটি একটি * int- এ একটি পরিবর্তে এর *int64সম্পাদনা: না এটা না। এই সম্পর্কে দুঃখিত।

সম্পাদনা করুন:

স্পষ্টতই আমার প্রশ্নের অনেকটা অস্পষ্টতা ছিল। আমি একটি উপায় খুঁজছি আক্ষরিক রাষ্ট্র একটি *int64। এটি কোনও কনস্ট্রাক্টরের অভ্যন্তরে বা আক্ষরিক কাঠামোর মানগুলিতে বা অন্য ফাংশনের পক্ষে যুক্তি হিসাবেও ব্যবহার করা যেতে পারে। তবে সহায়ক ফাংশন বা অন্য ধরণের ব্যবহার করা সমাধানগুলি আমি খুঁজছি না।


4
ইন পয়েন্টারগুলি দুর্ভাগ্যজনক কারণ ইন পয়েন্টার হিসাবে সমান পরিমাণ স্থান গ্রহণ করে, তাই আপনি স্থান সংরক্ষণ করছেন না। এটি কেবলমাত্র একটি নুল মান যুক্ত করে যা সাধারণত এটির চেয়ে বেশি জটিলতা। বেশিরভাগ ক্ষেত্রে একটি 0 জরিমানা হবে। আপনার যদি অতিরিক্ত মূল্য প্রয়োজন হয় তবে "ইসভালিডসোমফিল্ড" বুলটিও কাজ করে এবং যদি আপনি সেই বোলটিকে আরও ভাল নাম দেন তবে আপনার কেন সেই অতিরিক্ত মান প্রয়োজন কেন তা পড়তে পারা যায় which
ভুটসৌরাস

4
আপনি প্যাকেজ পয়েন্টার ব্যবহার করতে পারেন , উদাহরণস্বরূপ:var _ *int64 = pointer.Int64(64)
Xor

এটি এমন করুণাময় যে এটি করতে সক্ষম হতে আমাদের একটি ফাংশন বা একটি লাইব্রেরি লিখতে হবে।
নারকেল

উত্তর:


224

যান ভাষা স্পেসিফিকেসন ( ঠিকানা অপারেটার ) (একটি নয় একটি সাংখ্যিক ধ্রুবক এর ঠিকানা নিতে অনুমতি দেয় না untyped অথবা একটি এর টাইপ করা ধ্রুবক)।

অপারেন্ডটি অবশ্যই ঠিকানাযোগ্য , এটি হয় একটি ভেরিয়েবল, পয়েন্টার ইন্ডায়ারেশন বা স্লাইস ইনডেক্সিং অপারেশন; বা কোনও ঠিকানাযোগ্য স্ট্রাক্ট অপারেন্ডের ক্ষেত্র নির্বাচনকারী; বা একটি ঠিকানাযোগ্য অ্যারের একটি অ্যারে সূচক অপারেশন। ঠিকানার প্রয়োজনীয়তার ব্যতিক্রম হিসাবে, x[এর অভিব্যক্তিতে &x] একটি (সম্ভবত প্যারেনসাইজড) যৌগিক আক্ষরিকও হতে পারে ।

কেন এটি অনুমোদিত নয় তা যুক্তির জন্য, সম্পর্কিত প্রশ্ন দেখুন: চলতে চলতে স্থির ঠিকানা সন্ধান করুন । একটি অনুরূপ প্রশ্ন (একইভাবে এটির ঠিকানা নেওয়ার অনুমতি নেই): আমি কীভাবে কোনও অপারেশনের ফলাফলের জন্য রেফারেন্স সঞ্চয় করতে পারি?

আপনার বিকল্পগুলি ( গো খেলার মাঠে সমস্ত চেষ্টা করুন ):

1) সাথে new()

new()নতুন শূন্য-মূল্যের বরাদ্দ করতে int64এবং এর ঠিকানা পেতে আপনি কেবল বিল্টিন ফাংশনটি ব্যবহার করতে পারেন :

instance := SomeType{
    SomeField: new(int64),
}

তবে মনে রাখবেন যে এটি কেবল যে কোনও ধরণের শূন্য মানের একটি পয়েন্টার বরাদ্দ এবং প্রাপ্ত করতে ব্যবহৃত হতে পারে।

2) সাহায্যকারী পরিবর্তনশীল সহ

শূন্য-না-থাকা উপাদানগুলির জন্য সবচেয়ে সহজ এবং প্রস্তাবিত হ'ল একটি সহায়ক ভেরিয়েবল ব্যবহার করা যার ঠিকানা নেওয়া যেতে পারে:

helper := int64(2)
instance2 := SomeType{
    SomeField: &helper,
}

3) সহায়ক ফাংশন সহ

দ্রষ্টব্য: অ-শূন্য মানের জন্য একটি পয়েন্টার অর্জনের জন্য সহায়ক ফাংশনগুলি আমার github.com/icza/goxলাইব্রেরিতে, goxপ্যাকেজে পাওয়া যায়, যাতে আপনার যেখানে প্রয়োজন সেখানে আপনার সমস্ত প্রকল্পে এগুলি যুক্ত করতে হবে না।

বা আপনার যদি এটির অনেক বার প্রয়োজন হয়, আপনি একটি সহায়তা ফাংশন তৈরি করতে পারেন যা একটি বরাদ্দ করে এবং প্রদান করে *int64:

func create(x int64) *int64 {
    return &x
}

এবং এটি ব্যবহার:

instance3 := SomeType{
    SomeField: create(3),
}

নোট করুন যে আমরা আসলে কিছুই বরাদ্দ করি নি, গো সংকলক যখন ফাংশন আর্গুমেন্টের ঠিকানা ফেরত দিয়েছিল তখন তা করেছিল। গো সংকলক এস্কেপ বিশ্লেষণ সম্পাদন করে এবং যদি ফাংশন থেকে বাঁচতে পারে তবে গাদা (স্তরের পরিবর্তে) স্থানীয় ভেরিয়েবলগুলি বরাদ্দ করে। বিশদ জন্য, দেখুন একটি গো ফাংশন একটি স্থানীয় অ্যারের এক টুকরা ফিরে নিরাপদ?

4) একটি-লাইনার বেনামে ফাংশন সহ

instance4 := SomeType{
    SomeField: func() *int64 { i := int64(4); return &i }(),
}

বা (সংক্ষিপ্ত) বিকল্প হিসাবে:

instance4 := SomeType{
    SomeField: func(i int64) *int64 { return &i }(4),
}

5) স্লাইস আক্ষরিক, সূচীকরণ এবং ঠিকানা গ্রহণ সহ

আপনি যদি *SomeFieldঅন্যটি হতে চান 0তবে আপনার ঠিকানা দেওয়ার মতো কিছু দরকার।

আপনি এখনও এটি করতে পারেন, তবে এটি কুৎসিত:

instance5 := SomeType{
    SomeField: &[]int64{5}[0],
}
fmt.Println(*instance2.SomeField) // Prints 5

এখানে যা ঘটে তা হ'ল একটি []int64স্লাইস আক্ষরিক দিয়ে তৈরি করা হয়, যার একটি উপাদান থাকে ( 5)। এবং এটি সূচকযুক্ত (0 তম উপাদান) এবং 0 তম উপাদানটির ঠিকানা নেওয়া হয়। পটভূমিতে একটি অ্যারেও [1]int64বরাদ্দ করা হবে এবং স্লাইসের জন্য ব্যাকিং অ্যারে হিসাবে ব্যবহৃত হবে। সুতরাং এখানে প্রচুর বয়লারপ্লেট রয়েছে।

6) একটি সহায়ক কাঠামোর সাথে আক্ষরিক

আসুন ঠিকানার প্রয়োজনীয়তার ব্যতিক্রমগুলি পরীক্ষা করে দেখি:

ঠিকানার প্রয়োজনীয়তার ব্যতিক্রম হিসাবে, x[এর অভিব্যক্তিতে &x] একটি (সম্ভবত প্যারেনসাইজড) যৌগিক আক্ষরিকও হতে পারে ।

এর অর্থ হ'ল একটি যৌগিক আক্ষরিকের ঠিকানা গ্রহণ করা, যেমন একটি কাঠামো আক্ষরিক ঠিক আছে। যদি আমরা এটি করি, আমাদের স্ট্রাক্টের মূল্য বরাদ্দ হবে এবং এটিতে একটি পয়েন্টার পাওয়া যাবে। তবে যদি তা হয় তবে আর একটি প্রয়োজনীয়তা আমাদের কাছে উপলভ্য হবে: "অ্যাড্রেসিয়েবল স্ট্রাক্ট অপারেন্ডের ক্ষেত্র নির্বাচনকারী" । সুতরাং যদি স্ট্রাক্ট আক্ষরিক ধরণের কোনও ক্ষেত্র থাকে তবে আমরা সেই ক্ষেত্রের ঠিকানাও int64নিতে পারি!

আসুন এই বিকল্পটি কার্যকরভাবে দেখি। আমরা এই মোড়কের কাঠামোর ধরণটি ব্যবহার করব:

type intwrapper struct {
    x int64
}

এবং এখন আমরা করতে পারি:

instance6 := SomeType{
    SomeField: &(&intwrapper{6}).x,
}

এটি নোট করুন

&(&intwrapper{6}).x

নিম্নলিখিতটির অর্থ:

& ( (&intwrapper{6}).x )

তবে নির্বাচক অভিব্যক্তির& ফলাফলের জন্য ঠিকানা অপারেটর প্রয়োগ করা হওয়ায় আমরা "বাইরের" প্রথম বন্ধনী বাদ দিতে পারি ।

এছাড়াও নোট করুন যে পটভূমিতে নিম্নলিখিতটি ঘটবে (এটি একটি বৈধ বাক্য গঠন):

&(*(&intwrapper{6})).x

7) সহকারী বেনামে কাঠামোগত আক্ষরিক সাথে

নীতিটি # 6 কেসের মতো একই, তবে আমরা একটি বেনামি কাঠামোগত আক্ষরিকও ব্যবহার করতে পারি, সুতরাং কোনও সহায়ক / মোড়কের কাঠামোর ধরণের সংজ্ঞা প্রয়োজন নেই:

instance7 := SomeType{
    SomeField: &(&struct{ x int64 }{7}).x,
}

4
এটি স্থানধারক সহ প্রশ্নটির শেষ উদাহরণের চেয়ে কার্যত instanceভিন্ন , কারণ দুটি ডিফেরেন্ট অবজেক্ট দুটি পৃথক আকারের দিকে নির্দেশ করবে int64। তবে এটি মনে হয় ওপিদের পর্যাপ্ত পরিমাণের সাথে মিলিত হয়েছে
রায়ান হেইনিং

4
এটি অবশ্যই আমার প্রশ্নের উত্তর দেয়। কিন্তু এটা তোলে আমাকে খুব বিচলিত বোধ করেন: &[]int64{2}[0]আমি এ ধ্রুবক বিবরণ উপর ভিত্তি করে মত মনে blog.golang.org/constants এই উচিত ঠিক যেমন কাজ &0
এইগুই

@ রায়ানহাইনিং এবং যদি একই ঠিকানাটি বরাদ্দ করা হয় তবে এটির কাজ কী হবে? দুটি পৃথক instanceবস্তু যদি একই int64দিকে নির্দেশ করে এবং একটি পয়েন্ট করা অবজেক্টটি পরিবর্তন করে, তবে উভয়ই পরিবর্তিত হবে। এবং এখন যদি আপনি 3 য় তৈরি করতে একই আক্ষরিক ব্যবহার করেন instance? একই ঠিকানাটি এখন ভিন্ন int64মানের দিকে ইঙ্গিত করবে ... তাই আলাদা ঠিকানা ব্যবহার করা উচিত, তবে কেন প্রথম 2 এর ক্ষেত্রে একই ব্যবহার করা যেতে পারে?
আইজজা

@ আইকজা আপনি সাধারণত তাদের একই জিনিসটির দিকে ইঙ্গিত করতে চান না, আমি বলছি না আপনি যা করবেন। আমি কেবল পার্থক্যটি নির্দেশ করছি।
রায়ান হেইনিং

4
সংকলনের সময় @ কনস্লো কনস্ট্যান্টগুলি মূল্যায়ন করা হয়। একটি বৈধ পয়েন্টার মান, একটি বৈধ মেমরি ঠিকানা কেবল রানটাইম এ উপস্থিত থাকে, সুতরাং এটি ধ্রুবকের মতো নয়।
আইজজা

5

সমস্যাটি সমাধান করার জন্য একটি ফাংশন ব্যবহার করুন যা কোনও int64 ভেরিয়েবলের ঠিকানা ফেরত দেয়।

নীচের কোডে আমরা ফাংশনটি ব্যবহার করি fযা একটি পূর্ণসংখ্যা গ্রহণ করে এবং একটি পয়েন্টার মান দেয় যা পূর্ণসংখ্যার ঠিকানা ধারণ করে। এই পদ্ধতিটি ব্যবহার করে আমরা সহজেই উপরের সমস্যাটি সমাধান করতে পারি।

type myStr struct {
    url *int64
}

func main() {
    f := func(s int64) *int64 {
        return &s
    }
    myStr{
        url: f(12345),
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.