#swift #swift5 #autodiff
Вопрос:
Я хотел бы иметь следующее:
import _Differentiation
struct S {
var f: @differentiable(reverse) (Double, Double) -> Double
}
но компилятор жалуется Error: Abort trap: 6
, и начало трассировки стека
Assertion failed: (isa<X>(Val) amp;amp; "cast<Ty>() argument of incompatible type!"), function cast, file Casting.h, line 269.
Если переменная-член является функцией одного параметра, программа строит:
import _Differentiation
struct S {
var f: @differentiable(reverse) (Double) -> Double
}
но два или более параметров не допускаются.
Мы можем написать функцию, которая имеет дифференцируемую функцию двух параметров в качестве параметра:
import _Differentiation
func g(f: @differentiable(reverse) (Double, Double) -> Double) {
// function body
}
Если функция может иметь параметр такого типа, почему структура не может иметь переменную-член этого типа?
Ответ №1:
Это может быть достигнуто путем создания структуры и/или функции переменной-члена fileprivate
или private
управления доступом:
import _Differentiation
struct S {
fileprivate var f: @differentiable(reverse) (Double, Double, Double) -> Double
}
или
import _Differentiation
fileprivate struct S {
public var f: @differentiable(reverse) (Double, Double, Double) -> Double
}
Обратите внимание, что во втором примере это f
может быть public
, потому S
что ограничено по крайней мере fileprivate
.
Обходной путь состоит в том, чтобы сделать f
функцию другой дифференцируемой структуры данных, например:
import _Differentiation
struct S {
struct Tuple: Differentiable {
var x: Double
var y: Double
@differentiable(reverse)
init(x: Double, y: Double) {
self.x = x
self.y = y
}
}
var f: @differentiable(reverse) (Tuple) -> Double
}