@@ -41,20 +41,39 @@ see :doc:`../LanguageGuide/BasicOperators` and :doc:`../LanguageGuide/AdvancedOp
41
41
For information about the operators provided by the Swift standard library,
42
42
see `Operator Declarations <https://developer.apple.com/documentation/swift/operator_declarations >`_.
43
43
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
46
59
as 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,
48
66
see :ref: `Functions_InOutParameters `.
49
67
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 `.
51
72
52
73
.. syntax-grammar ::
53
74
54
- Grammar of a prefix expression
75
+ Grammar of an in-out expression
55
76
56
- prefix-expression --> prefix-operator-OPT postfix-expression
57
- prefix-expression --> in-out-expression
58
77
in-out-expression --> ``& `` identifier
59
78
60
79
@@ -1762,6 +1781,102 @@ can enable syntactic sugar for function call syntax
1762
1781
by declaring one of several methods,
1763
1782
as described in :ref: `Declarations_SpecialFuncNames `.
1764
1783
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
+
1765
1880
.. syntax-grammar ::
1766
1881
1767
1882
Grammar of a function call expression
0 commit comments