সুইফটে ভেরিয়েবলের সংখ্যা সহ একটি ফাংশনে একটি অ্যারে পাস করা


151

ইন সুইফট প্রোগ্রামিং ভাষা , এটা বলেন:

ক্রিয়াকলাপগুলি একটি অ্যারেতে সংগ্রহ করে, একটি পরিবর্তনশীল সংখ্যক যুক্তিও নিতে পারে।

  func sumOf(numbers: Int...) -> Int {
      ...
  }

যখন আমি এই জাতীয় ক্রিয়াকলাপকে কমা দ্বারা বিচ্ছিন্ন সংখ্যার তালিকার (O যোগফল (1, 2, 3, 4) দিয়ে কল করি তখন সেগুলি ফাংশনের অভ্যন্তরে অ্যারে হিসাবে উপলব্ধ করা হয়।

প্রশ্ন: আমার যদি ইতিমধ্যে এই ফাংশনে পাস করতে চাই এমন সংখ্যার একটি অ্যারে থাকে?

let numbers = [1, 2, 3, 4]
sumOf(numbers)

এটি সংকলক ত্রুটির সাথে ব্যর্থ হয়েছে, "সরবরাহিত যুক্তি গ্রহণ করে '' __ রূপান্তর '' এর জন্য একটি ওভারলোড খুঁজে পাওয়া যায়নি"। একটি বিদ্যমান অ্যারেটিকে উপাদানগুলির তালিকায় পরিণত করার কোনও উপায় আছে যা আমি একটি বৈকল্পিক ফাংশনে যেতে পারি?


1
পরিবর্তে একটি পূর্ণসংখ্যা অ্যারে নিতে ফাংশনটি কনফিগার করবেন না কেন?
মিক ম্যাককালাম

27
অবশ্যই, তবে আমি ফাংশনটির লেখক নাও হতে পারি এবং এটি পরিবর্তন করতে (বা চাই) নাও করতে পারি।
ওলে বেগম্যান

উত্তর:


97

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


3
ভাষাতে স্প্ল্যাটিং এখনও চলছে? আমি কল করার চেষ্টা করছিsumOf(...numbers)
নোটিডার্ট

হতাশ! আমি এটিকে এমনকি নিজের লগ কলগুলিকে নিচে নামিয়ে দেওয়ার চেষ্টা করার মতো সহজ কিছু দিয়ে আঘাত করেছি print!
মার্ক এ। ডোনোহো

65

এখানে আমি একটি কাজ প্রায় পাওয়া গেছে। আমি জানি এটি আপনি যা চান ঠিক তা নয় তবে মনে হচ্ছে এটি কাজ করছে।

পদক্ষেপ 1: আপনি যে ক্রিয়াকলাপটি চান তা ভ্যারিয়্যাডিক যুক্তির পরিবর্তে অ্যারে দিয়ে ঘোষণা করুন:

func sumOf(numbers: [Int]) -> Int {
    var total = 0
    for i in numbers {
        total += i
    }
    return total
}

পদক্ষেপ 2: আপনার বৈকল্পিক ফাংশনের মধ্যে থেকে এটিকে কল করুন:

func sumOf(numbers: Int...) -> Int {
    return sumOf(numbers)
}

পদক্ষেপ 3: যেভাবেই কল করুন:

var variadicSum = sumOf(1, 2, 3, 4, 5)
var arraySum = sumOf([1, 2, 3, 4, 5])

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

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


ধন্যবাদ, আমি অনেকটা পছন্দ করি বৈশিষ্ট্যটি এখনও উপলভ্য নয় এমন সরকারী নিশ্চিতকরণের লিঙ্কটি সন্ধান করার জন্য আমি মনোজल्डদের "সঠিক" উত্তরটি দেব। আমি আশা করি তুমি বুঝতে পেরেছ.
ওলে বেগম্যান

আপনি সম্ভবত গাইড এবং আপনার মজাদার যোগফল অনুসরণ করছেন (সংখ্যা: [ইনট]) -> ইন্ট আসলে গড় গণনা করছে
gfelisberto

18

আপনি ফাংশনটি কাস্ট করতে পারেন:

typealias Function = [Int] -> Int
let sumOfArray = unsafeBitCast(sumOf, Function.self)
sumOfArray([1, 2, 3])

গ্রেট! এটি একাধিক (নামযুক্ত) পরামিতিগুলির সাথেও কাজ করে; যেমন: func sumOf(foo numbers: Int..., bar: Bool) -> Int {};প্রয়োজনtypealias Function = (foo: [Int], bar: Bool) -> Int;
টমাসআর

গ্রেট! আমার জীবন রক্ষা করো.
জেরিঝো

আমি কীভাবে অ্যানোবজেক্টের সাথে একই জিনিস করতে পারি ...? stackoverflow.com/questions/42016358/… ধন্যবাদ।
জেরিঝো

এটি একটি খুব খারাপ ধারণা। এটি পুরোপুরি শূন্যের নিশ্চয়তা আছে।
idmean

1
পুনঃটুইট যতদূর আমি বলতে পারি এমন কিছুই নেই যা আপনাকে কেবল একটি কলযোগ্য প্রকারের সাহায্যে অন্যকে ব্যবহার করার অনুমতি দেয় unsafeBitCast। এটি আজ কাজ করতে পারে, তবে কোনও রেফারেন্স না বললে কম্পাইলারের পরবর্তী সংস্করণটি এখানে আক্ষরিকভাবে কিছু করতে পারে (সংকলক ত্রুটি / ক্রাশ / এলোমেলোভাবে কোড চালানো কোড ...)। অনিরাপদ বিটকাস্ট সম্পর্কে গুরুতর- দৃষ্টিভঙ্গি সতর্কতা দেখুন
ইডমিয়ান

15

আপনি যেমন কোনও সহায়ক ফাংশন ব্যবহার করতে পারেন:

func sumOf (numbers : [Int])  -> Int { return numbers.reduce(0, combine: +) }
func sumOf (numbers : Int...) -> Int { return sumOf (numbers) }

12
প্রদত্ত অ্যারেগুলির জন্য একটি সংস্করণ রয়েছে। আমি ভেবেছিলাম যে প্রশ্নের মূল ভিত্তিটি হ'ল মূল ফাংশনটি নেয় Int...এবং (সহজেই) পরিবর্তন করা যায় না?

2
@ ডেলানান: সঠিক। আমার কাছে মনে হচ্ছে যে ভেরিয়েডিক আর্গুমেন্টগুলি যেভাবেই অ্যারেতে রূপান্তরিত হয়েছে তা প্রদত্ত একটি ভেরিয়াদিক ফাংশনে অ্যারে পাস করার উপায় থাকা উচিত।
ওলে বেগম্যান

1
যে ভাষাগুলিতে ফাংশনগুলিতে স্কিমের মতো পরিবর্তনশীল সংখ্যক আর্গুমেন্ট গ্রহণ করা হয় তাদের একটি applyপদ্ধতি রয়েছে। আমি কিছু লোককে 'স্প্ল্যাটিং' বলে ডাকি।
GoZoner

1
sumArrayএখানে রেফারেন্স কি ?
রব

2

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

আমার ক্ষেত্রে আমি কেবল একটি অ্যারে পাস করতে চেয়েছিলাম:

func sumOf(numbers: Array<Int>) -> Int {
    var sum = 0
    for number in numbers {
        sum += number
    }
    return sum
}

var someNums = [8,7,2,9,12]
sumOf(someNums)
sumOf([10, 15, 20])

কেবল ভাগ করে নিতে চেয়েছিলেন, অন্য কেউ যদি আমার মতো ভাবছিল। বেশিরভাগ সময় আমি এই জাতীয় অ্যারে পাস করতে পছন্দ করি তবে আমি "দ্রুত" এখনও ভাবি না। :)


1

আমি এটি করেছি (র‍্যাপার + আইডেন্টিটি ম্যাপিং):

func addBarButtonItems(types: REWEBarButtonItemType...) {
    addBarButtonItems(types: types.map { $0 })
}

func addBarButtonItems(types: [REWEBarButtonItemType]) {
    // actual implementation
}

0

সুইফট 5

এটি @dynamicCallableবৈশিষ্ট্য সহ এমন একটি পদ্ধতির যা ওভারলোডিং এড়াতে বা আপনাকে কল unsafeBitCastকরার জন্য একটি নির্দিষ্ট structকরা উচিত :

@dynamicCallable
struct SumOf {
    func dynamicallyCall(withArguments args: [Int]) -> Int {
        return args.reduce(0, +)
    }
}

let sum = SumOf()

// Use a dynamic method call.
sum(1, 2, 3) // 6

// Call the underlying method directly.
sum.dynamicallyCall(withArguments: [1, 2, 3]) // 6
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.