PC パソコン

How to Fix “Ambiguous Use of” in Swift

When calling a Swift function, method, initializer, or property, Xcode may report an error such as:

Ambiguous use of 'show'

You may also see:

Ambiguous use of 'init'

This error means that the compiler has multiple valid-looking candidates and does not have enough type information to choose exactly one of them.

Common causes include similar overloads, ambiguous numeric literals, nil values without an expected optional type, empty collections, overloaded function references, ambiguous closures, unresolved generic parameters, competing protocol-extension members, same-named declarations from multiple modules, and SwiftUI initializers that cannot be uniquely selected.

The usual fix is to provide more type context so Swift can eliminate every candidate except the one you intend to call.

  1. What does “Ambiguous use of” mean?
  2. How is this different from “Invalid redeclaration”?
  3. Typical situations where this error appears
  4. Common causes
    1. 1. Too many similar overloads
    2. 2. An ambiguous numeric literal
    3. 3. Passing nil to multiple optional overloads
    4. 4. Passing an empty array to multiple collection overloads
    5. 5. An overloaded function reference has no function type
    6. 6. An overloaded initializer or function is passed directly to map
    7. 7. A closure parameter type cannot be inferred
    8. 8. A closure return type is unclear
    9. 9. A generic parameter remains unresolved
    10. 10. Optional and non-optional overloads are both available
    11. 11. Multiple protocol extensions provide the same method
    12. 12. Protocol requirements and extension methods compete
    13. 13. Same-named declarations come from multiple modules
    14. 14. SwiftUI exposes many initializer overloads
    15. 15. A Binding is confused with its wrapped value
    16. 16. Picker selection and tag types do not line up
    17. 17. Multiple generic initializers are available
    18. 18. Literal-convertible custom types increase the candidate set
    19. 19. Default arguments make overloads overlap
    20. 20. Another compiler error is the real cause
  5. What to check first
    1. 1. Identify the declaration named in the diagnostic
    2. 2. Inspect available overloads with Xcode autocomplete
    3. 3. Use Quick Help or Jump to Definition
    4. 4. Check the earliest compiler diagnostic
  6. Solution 1: Add an explicit variable type
  7. Solution 2: Explicitly convert or cast the argument
  8. Solution 3: Give nil a concrete optional type
  9. Solution 4: Give an empty collection an element type
  10. Solution 5: Give an overloaded function reference a function type
  11. Solution 6: Replace an ambiguous function reference with a closure
  12. Solution 7: Specify the closure parameter type
  13. Solution 8: Specify the closure return type
  14. Solution 9: Specify the map result type
  15. Solution 10: Specify the compactMap output type
  16. Solution 11: Make a generic container concrete
  17. Solution 12: Add result context to generic functions
  18. Solution 13: Reduce the number of similar overloads
  19. Solution 14: Avoid overlapping overloads created by default arguments
  20. Solution 15: Simplify optional overloads
  21. Solution 16: Resolve competing protocol-extension methods
  22. Solution 17: Qualify same-named types by module
  23. Solution 18: Wrap confusing external APIs
  24. Solution 19: Make initializer arguments explicit
  25. Solution 20: Pass SwiftUI bindings correctly
  26. Solution 21: Check custom SwiftUI bindings
  27. Solution 22: Keep Picker selection and tag types consistent
  28. Solution 23: Unwrap SwiftUI optionals before passing them on
  29. Solution 24: Split large SwiftUI expressions
  30. Solution 25: Break complex expressions into typed intermediate values
  31. Solution 26: Specify numeric types explicitly
  32. Solution 27: Convert Int, Double, CGFloat, and similar types deliberately
  33. Solution 28: Use clearer function names instead of excessive overloading
  34. Solution 29: Reduce nested conversions at the call site
  35. Solution 30: Redesign your own ambiguous APIs
  36. If Xcode says “Ambiguous use of init”
  37. If Xcode says “Ambiguous use of subscript”
  38. If Xcode reports an ambiguous operator
  39. If the error occurs in SwiftUI
  40. If the error occurs in map or compactMap
  41. If the error occurs with protocol extensions
  42. If same-named types come from multiple modules
  43. Will Clean Build Folder fix it?
  44. Should you delete DerivedData?
  45. What you should avoid
  46. Fast troubleshooting checklist
  47. Summary

What does “Ambiguous use of” mean?

Swift supports function overloading.

For example:

func show(_ value: Int) { print("Int: \(value)") }

func show(_ value: Double) {
print("Double: (value)")
}

In straightforward calls, Swift can often infer the intended overload from the argument type.

In more complicated expressions involving generics, literals, closures, or optionals, multiple candidates may remain equally valid.

Swift then reports:

Ambiguous use of 'show'

How is this different from “Invalid redeclaration”?

An error such as:

Invalid redeclaration of 'show'

means the declarations themselves conflict because Swift cannot treat them as distinct definitions.

By contrast:

Ambiguous use of 'show'

usually means the declarations are individually valid, but the call site does not provide enough information to choose one.

Key point: Invalid redeclaration is primarily a declaration problem. Ambiguous use is primarily an overload-resolution or type-inference problem at the use site.

Typical situations where this error appears

  • Several function overloads have similar signatures
  • Multiple initializer candidates remain valid
  • A numeric literal has no clear concrete type
  • nil does not reveal its wrapped optional type
  • An empty array or dictionary has no element type
  • A closure parameter cannot be inferred
  • A closure return type cannot be inferred
  • An overloaded function reference is passed to map or another higher-order function
  • A generic parameter remains unresolved
  • Several protocol extensions provide the same member name
  • Multiple imported modules contain the same type or function name
  • SwiftUI has several compatible-looking generic initializers
  • A Binding is confused with a plain value
  • Optional and non-optional overloads compete

Common causes

1. Too many similar overloads

func process(_ value: Int) { }

func process(_ value: Double) {
}

If the argument’s concrete numeric type is not known, both candidates may remain possible.

2. An ambiguous numeric literal

Swift numeric literals receive their concrete type from context.

When that context is missing or multiple numeric overloads fit, overload resolution can become ambiguous.

3. Passing nil to multiple optional overloads

func setValue(_ value: String?) { }

func setValue(_ value: Int?) {
}

setValue(nil)

nil alone does not tell Swift whether you mean String? or Int?.

4. Passing an empty array to multiple collection overloads

func process(_ values: [String]) { }

func process(_ values: [Int]) {
}

process([])

The empty array has no element-type information.

5. An overloaded function reference has no function type

func convert(_ value: Int) -> String { String(value) }

func convert(_ value: Double) -> String {
String(value)
}

let handler = convert

Swift cannot determine which convert function should be stored.

6. An overloaded initializer or function is passed directly to map

let values = numbers.map(String.init)

If the input or output type is insufficiently constrained, one of several String initializers may appear valid.

7. A closure parameter type cannot be inferred

someMethod { value in print(value) }

Generic or overloaded APIs may leave the type of value unresolved.

8. A closure return type is unclear

Different branches may produce incompatible results, or all branches may return nil without identifying an output type.

9. A generic parameter remains unresolved

func make<T>() -> T { fatalError() }

let value = make()

This may produce a generic inference error directly, but in an overloaded expression it can also contribute to an ambiguous-use diagnostic.

10. Optional and non-optional overloads are both available

func show(_ value: String) { }

func show(_ value: String?) {
}

Optional promotion and surrounding context can make overload selection harder to reason about.

11. Multiple protocol extensions provide the same method

A concrete type conforming to several protocols may inherit competing default implementations with the same member name.

12. Protocol requirements and extension methods compete

Complex protocol hierarchies and conditional extensions can create several available members with similar signatures.

13. Same-named declarations come from multiple modules

Two imported frameworks may both define User, Configuration, or another common name.

14. SwiftUI exposes many initializer overloads

Views such as TextField, Button, Picker, and navigation APIs often have several generic initializers.

A missing Binding or type mismatch can leave more than one candidate in play or eliminate the one you intended.

15. A Binding is confused with its wrapped value

With:

@State private var name = ""

name is String, while $name is Binding<String>.

16. Picker selection and tag types do not line up

The Picker’s generic selection type must be consistent with its tag values.

17. Multiple generic initializers are available

Conditional initializers and protocol-constrained initializers can overlap for the same concrete type.

18. Literal-convertible custom types increase the candidate set

Types conforming to protocols such as ExpressibleByIntegerLiteral or ExpressibleByStringLiteral can compete with standard-library types in an underconstrained expression.

19. Default arguments make overloads overlap

Two overloads may become callable with the same argument list because their remaining parameters have defaults.

20. Another compiler error is the real cause

Especially in SwiftUI or complex generic expressions, an inner type error may prevent normal overload resolution and surface as an ambiguous-use error elsewhere.

What to check first

1. Identify the declaration named in the diagnostic

For example:

Ambiguous use of 'init'

means the compiler cannot choose among multiple initializers.

2. Inspect available overloads with Xcode autocomplete

Retype the function or initializer name and compare the candidate signatures Xcode offers.

3. Use Quick Help or Jump to Definition

Compare parameter labels, parameter types, generic constraints, and return types.

4. Check the earliest compiler diagnostic

The ambiguous-use message may be secondary.

Important: In SwiftUI especially, fix earlier Binding, optional, argument-label, and generic errors before treating the ambiguous-use message as the root cause.

Solution 1: Add an explicit variable type

let value: Int = 10

Now overload resolution has a concrete numeric type.

Solution 2: Explicitly convert or cast the argument

show(10 as Int)

or:

show(10.0 as Double)

Note: Use an explicit type only when it represents your actual intent. Do not add arbitrary casts merely to silence the compiler.

Solution 3: Give nil a concrete optional type

setValue( nil as String? )

or:

let value: String? = nil setValue(value)

Solution 4: Give an empty collection an element type

process( [] as [String] )

or:

let values: [String] = [] process(values)

Solution 5: Give an overloaded function reference a function type

func convert(_ value: Int) -> String { String(value) }

func convert(_ value: Double) -> String {
String(value)
}

let handler: (Int) -> String = convert

This selects the Int overload.

Solution 6: Replace an ambiguous function reference with a closure

let strings = numbers.map { value in String(value) }

The closure often gives Swift clearer input-type context than an overloaded function reference.

Solution 7: Specify the closure parameter type

let result = values.map { (value: Int) in
String(value)

}

Solution 8: Specify the closure return type

let result = values.map { (value: Int) -> String in
String(value)

}

Solution 9: Specify the map result type

let strings: [String] = numbers.map { value in String(value) }

Solution 10: Specify the compactMap output type

let numbers: [Int] = strings.compactMap { (text: String) -> Int? in
    Int(text)
}

Solution 11: Make a generic container concrete

let box: Box<String> = Box(value: nil)

Solution 12: Add result context to generic functions

func makeValue<T>() -> T { fatalError() }

let value: User = makeValue()

Swift can now infer T as User.

Solution 13: Reduce the number of similar overloads

If an API is difficult to call correctly, consider clearer names:

func loadUserByID(_ id: Int) { }

func loadUserByName(_ name: String) {
}

This removes overload-resolution work from the call site entirely.

Solution 14: Avoid overlapping overloads created by default arguments

Problematic API design:

func show( value: Int, animated: Bool = true ) { }

func show(
value: Int,
highlighted: Bool = false
) {
}

Both can be called as:

show(value: 10)

Rename or redesign one overload so the call is unique.

Solution 15: Simplify optional overloads

func show(_ value: String) { }

func show(_ value: String?) {
}

Check whether both are really necessary. One optional-aware implementation may be easier to use and maintain.

Solution 16: Resolve competing protocol-extension methods

protocol A { }

protocol B {
}

extension A {
func run() {
print("A")
}
}

extension B {
func run() {
print("B")
}
}

struct Worker: A, B {
func run() {
print("Worker")
}
}

An explicit implementation on the concrete type removes the ambiguity.

Solution 17: Qualify same-named types by module

FrameworkA.User

versus:

FrameworkB.User

Solution 18: Wrap confusing external APIs

If several imported functions share similar names, create an application-level wrapper with a clearer purpose:

func loadLocalUser( id: Int ) { LocalSDK.load(id: id) }

Solution 19: Make initializer arguments explicit

let value = SomeType( text: "Hello", count: 10 )

If literals remain ambiguous, add concrete argument types as well.

Solution 20: Pass SwiftUI bindings correctly

@State private var name = ""

TextField(
"Name",
text: $name
)

The initializer expecting Binding<String> needs $name, not the wrapped String value.

Solution 21: Check custom SwiftUI bindings

struct EditView: View { @Binding var text: String
var body: some View {
    TextField(
        "Text",
        text: $text
    )
}

}

struct ContentView: View {
@State private var text = ""

var body: some View {
    EditView(
        text: $text
    )
}

}

Solution 22: Keep Picker selection and tag types consistent

@State private var selected = 0

Picker(
"Option",
selection: $selected
) {
Text("One").tag(0)
Text("Two").tag(1)
}

If selection is Int, use Int tags as well.

Solution 23: Unwrap SwiftUI optionals before passing them on

if let selectedUser { UserView( user: selectedUser ) }

Solution 24: Split large SwiftUI expressions

var body: some View { VStack { headerView contentView } }

private var contentView: some View {
UserListView(
users: users
)
}

Smaller view-builder expressions make the real type mismatch easier to locate.

Solution 25: Break complex expressions into typed intermediate values

Instead of:

let result = users .map { $0.age } .map(String.init)

use:

let ages: [Int] = users.map { user in user.age }

let result: [String] =
ages.map { age in
String(age)
}

Solution 26: Specify numeric types explicitly

let width: Double = 10 let count: Int = 10

This is particularly useful when APIs have overloads for several numeric types.

Solution 27: Convert Int, Double, CGFloat, and similar types deliberately

let count = 10

let width: CGFloat =
CGFloat(count)

Solution 28: Use clearer function names instead of excessive overloading

func formatDate( _ value: Date ) -> String { ... }

func formatNumber(
_ value: Double
) -> String {
...
}

Clearer names can eliminate entire classes of overload ambiguity.

Solution 29: Reduce nested conversions at the call site

Move complex optional transformations and casts into intermediate values or helper methods so every step has a clear type.

Solution 30: Redesign your own ambiguous APIs

If your own APIs frequently trigger ambiguous-use errors, inspect the declarations themselves.

Common design problems include:

  • Overloads differing only in subtle labels
  • Default arguments that make several overloads callable the same way
  • Many optional and non-optional overload pairs
  • Overly complex generic constraints

Simplifying the API can be better than repeatedly adding type annotations at every call site.

If Xcode says “Ambiguous use of init”

Several initializers remain possible.

For example:

init(value: String?) init(value: Int?)

makes this ambiguous:

SomeType( value: nil )

Specify the intended optional type:

SomeType( value: nil as String? )

If Xcode says “Ambiguous use of subscript”

A collection or custom type may expose multiple subscript candidates.

Check the index or key type and the expected result type.

let dictionary: [String: Int] = [ "one": 1 ]

let value: Int? =
dictionary["one"]

If Xcode reports an ambiguous operator

Operators are overloaded too.

When numeric types differ, normalize them explicitly:

let intValue: Int = 10 let doubleValue: Double = 20

let result =
Double(intValue) + doubleValue

If the error occurs in SwiftUI

Use this troubleshooting order:

  1. Check for an earlier compiler error.
  2. Inspect the available initializer overloads.
  3. Verify argument labels.
  4. Verify argument types.
  5. Check Binding versus plain values.
  6. Check optional values.
  7. Check Picker selection and tag types.
  8. Check closure parameter types.
  9. Split a large body into smaller views.

If the error occurs in map or compactMap

Replace overloaded function references with explicit closures:

let strings: [String] = numbers.map { value in String(value) }

For compactMap:

let numbers: [Int] = strings.compactMap { text in Int(text) }

If the error occurs with protocol extensions

When several protocol extensions provide the same member, add an implementation to the concrete conforming type to define exactly which behavior should be used.

If same-named types come from multiple modules

Qualify the type explicitly:

FrameworkA.Configuration

or:

FrameworkB.Configuration

Will Clean Build Folder fix it?

Usually not.

This error is normally caused by overload resolution or insufficient type information in source code.

You can use:

Product → Clean Build Folder

as a secondary troubleshooting step, but it cannot resolve a genuinely ambiguous expression.

Should you delete DerivedData?

If Xcode indexing appears stale, you can try:

rm -rf ~/Library/Developer/Xcode/DerivedData/*

but deleting build artifacts does not choose between two overloads that are both valid according to your source code.

Note: Check overload candidates and type context before treating this as an Xcode cache problem.

What you should avoid

Do not add large numbers of forced casts or replace everything with Any just to silence an ambiguous-use error.

The compiler needs a clear statement of which type and overload your code intends to use.

Forced casts can reduce type safety and may introduce runtime crashes.

Prefer explicit variable types, argument types, closure types, and well-designed APIs.

Fast troubleshooting checklist

  1. Identify the function, method, initializer, or property named in the error.
  2. Inspect available overloads in Xcode autocomplete.
  3. Compare argument labels.
  4. Compare argument types.
  5. Add an explicit result type.
  6. Give numeric literals a concrete type.
  7. Give nil a concrete optional type.
  8. Give empty collections an element type.
  9. Give overloaded function references a function type.
  10. Specify closure parameter types.
  11. Specify closure return types.
  12. Specify generic types where necessary.
  13. Check competing protocol-extension methods.
  14. Check same-named declarations from multiple modules.
  15. In SwiftUI, check bindings, optionals, and initializer candidates.

Summary

Swift’s “Ambiguous use of” error means that the compiler has more than one possible function, method, initializer, property, subscript, or operator and cannot determine which candidate your code intends to use.

Common causes include similar overloads, numeric literals, nil values, empty collections, overloaded function references, closures, generic types, protocol extensions, same-named declarations from different modules, and SwiftUI initializer selection.

The most common solution is to provide more concrete type information. Add a variable type, argument type, result type, closure signature, optional type, or generic specialization so Swift can reduce the candidate set to one.

In SwiftUI, also check Binding versus plain values, optional data, Picker selection types, and any earlier compiler errors inside the view builder.

If ambiguous-use errors happen frequently in your own APIs, consider simplifying your overloads, removing overlapping default arguments, and using clearer function names rather than relying on increasingly complex type inference.