@@ -41,20 +41,39 @@ see :doc:`../LanguageGuide/BasicOperators` and :doc:`../LanguageGuide/AdvancedOp
4141For information about the operators provided by the Swift standard library,
4242see `Operator Declarations <https://developer.apple.com/documentation/swift/operator_declarations >`_.
4343
44- In addition to the standard library operators,
45- you use ``& `` immediately before the name of a variable that's being passed
44+ .. syntax-grammar ::
45+
46+ Grammar of a prefix expression
47+
48+ prefix-expression --> prefix-operator-OPT postfix-expression
49+ prefix-expression --> in-out-expression
50+
51+
52+ .. _Expressions_InOutExpression :
53+
54+ In-Out Expression
55+ ~~~~~~~~~~~~~~~~~
56+
57+ An :newTerm: `in-out expression ` marks a variable
58+ that's being passed
4659as an in-out argument to a function call expression.
47- For more information and to see an example,
60+
61+ .. syntax-outline ::
62+
63+ &<#expression#>
64+
65+ For more information about in-out parameters and to see an example,
4866see :ref: `Functions_InOutParameters `.
4967
50- .. TODO: Need to a brief write up on the in-out-expression.
68+ In-out expressions are also used
69+ when providing a non-pointer argument
70+ in a context where a pointer is needed,
71+ as described in :ref: `Expressions_ImplicitConversion `.
5172
5273.. syntax-grammar ::
5374
54- Grammar of a prefix expression
75+ Grammar of an in-out expression
5576
56- prefix-expression --> prefix-operator-OPT postfix-expression
57- prefix-expression --> in-out-expression
5877 in-out-expression --> ``& `` identifier
5978
6079
@@ -1762,6 +1781,102 @@ can enable syntactic sugar for function call syntax
17621781by declaring one of several methods,
17631782as described in :ref: `Declarations_SpecialFuncNames `.
17641783
1784+ .. _Expressions_ImplicitConversion :
1785+
1786+ Implicit Conversion to a Pointer Type
1787+ +++++++++++++++++++++++++++++++++++++
1788+
1789+ In a function call expression,
1790+ if the argument and parameter have a different type,
1791+ the compiler tries to make their types match
1792+ by applying one of the implicit conversions in the following list:
1793+
1794+ * ``inout SomeType `` can become
1795+ ``UnsafePointer<SomeType> `` or ``UnsafeMutablePointer<SomeType> ``
1796+ * ``inout Array<SomeType> `` can become
1797+ ``UnsafePointer<SomeType> `` or ``UnsafeMutablePointer<SomeType> ``
1798+ * ``Array<SomeType> `` can become ``UnsafePointer<SomeType> ``
1799+ * ``String `` can become ``UnsafePointer<CChar> ``
1800+
1801+ The following two function calls are equivalent:
1802+
1803+ .. testcode :: inout-unsafe-pointer
1804+
1805+ -> func unsafeFunction(pointer: UnsafePointer<Int>) {
1806+ -> // ...
1807+ >> print(pointer.pointee)
1808+ -> }
1809+ -> var myNumber = 1234
1810+ ---
1811+ -> unsafeFunction(pointer: &myNumber)
1812+ -> withUnsafePointer(to: myNumber) { unsafeFunction(pointer: $0) }
1813+ << 1234
1814+ << 1234
1815+
1816+ A pointer that's created by these implicit conversions
1817+ is valid only for the duration of the function call.
1818+ To avoid undefined behavior,
1819+ ensure that your code
1820+ never persists the pointer after the function call ends.
1821+
1822+ .. note ::
1823+
1824+ When implicitly converting an array to an unsafe pointer,
1825+ Swift ensures that the array's storage is contiguous
1826+ by converting or copying the array as needed.
1827+ For example, you can use this syntax
1828+ with an array that was bridged to ``Array ``
1829+ from an ``NSArray `` subclass that makes no API contract about its storage.
1830+ If you need to guarantee that the array's storage is already contiguous,
1831+ so the implicit conversion never needs to do this work,
1832+ use ``ContiguousArray `` instead of ``Array ``.
1833+
1834+ Using ``& `` instead of an explicit function like ``withUnsafePointer(to:) ``
1835+ can help make calls to low-level C functions more readable,
1836+ especially when the function takes several pointer arguments.
1837+ However, when calling functions from other Swift code,
1838+ avoid using ``& `` instead of using the unsafe APIs explicitly.
1839+
1840+ .. assertion :: implicit-conversion-to-pointer
1841+
1842+ >> import Foundation
1843+ >> func takesUnsafePointer(p: UnsafePointer<Int>) { }
1844+ >> func takesUnsafeMutablePointer(p: UnsafeMutablePointer<Int>) { }
1845+ >> func takesUnsafePointerCChar(p: UnsafePointer<CChar>) { }
1846+ >> func takesUnsafeMutablePointerCChar(p: UnsafeMutablePointer<CChar>) { }
1847+ >> var n = 12
1848+ >> var array = [1, 2, 3]
1849+ >> var nsarray: NSArray = [10, 20, 30]
1850+ >> var bridgedNSArray = nsarray as! Array<Int>
1851+ >> var string = "Hello"
1852+ ---
1853+ // bullet 1
1854+ >> takesUnsafePointer(p: &n)
1855+ >> takesUnsafeMutablePointer(p: &n)
1856+ ---
1857+ // bullet 2
1858+ >> takesUnsafePointer(p: &array)
1859+ >> takesUnsafeMutablePointer(p: &array)
1860+ >> takesUnsafePointer(p: &bridgedNSArray)
1861+ >> takesUnsafeMutablePointer(p: &bridgedNSArray)
1862+ ---
1863+ // bullet 3
1864+ >> takesUnsafePointer(p: array)
1865+ >> takesUnsafePointer(p: bridgedNSArray)
1866+ ---
1867+ // bullet 4
1868+ >> takesUnsafePointerCChar(p: string)
1869+ ---
1870+ // invailid conversions
1871+ >> takesUnsafeMutablePointer(p: array)
1872+ !$ error: cannot convert value of type '[Int]' to expected argument type 'UnsafeMutablePointer<Int>'
1873+ !! takesUnsafeMutablePointer(p: array)
1874+ !! ^
1875+ >> takesUnsafeMutablePointerCChar(p: string)
1876+ !$ error: cannot convert value of type 'String' to expected argument type 'UnsafeMutablePointer<CChar>' (aka 'UnsafeMutablePointer<Int8>')
1877+ !! takesUnsafeMutablePointerCChar(p: string)
1878+ !! ^
1879+
17651880.. syntax-grammar ::
17661881
17671882 Grammar of a function call expression
0 commit comments