Por que o Swift retorna um ponteiro inesperado ao converter uma String opcional em um UnsafePointer?
Percebi algum comportamento incomum ao trabalhar com uma biblioteca C que utilizava strings comoconst char *
(que é convertido em Swift comoUnsafePointer<Int8>!
); passando umString
funcionou como esperado, mas umString?
pareceu corromper a entrada. Considere o teste que escrevi:
func test(_ input: UnsafePointer<UInt8>?) {
if let string = input {
print(string[0], string[1], string[2], string[3], string[4], string[5])
} else {
print("nil")
}
}
let input: String = "Hello"
test(input)
Isso funciona como esperado, imprimindo uma lista terminada em nulo de bytes UTF-8 para a sequência de entrada:72 101 108 108 111 0
No entanto, se eu alterar a entrada para uma sequência opcional, ela se tornará:
let input: String? = "Hello"
Eu recebo um conjunto completamente diferente de valores no resultado (176 39 78 23 1 0
), mesmo que eu esperasse que fosse o mesmo. Passandonil
funciona como esperado.
A função da biblioteca C permiteNULL
no lugar de uma string, e às vezes eu quero passar isso também no Swift, então faz sentido que a string de entrada seja opcional.
Isso é um bug no Swift ou o Swift não foi projetado para lidar com este caso? De qualquer maneira, qual é a melhor maneira de lidar com este caso?
Editar
Parece ter algo a ver com vários argumentos. A função C:
void multiString(const char *arg0, const char *arg1, const char *arg2, const char *arg3) {
printf("%p: %c %c %c\n", arg0, arg0[0], arg0[1], arg0[2]);
printf("%p: %c %c %c\n", arg1, arg1[0], arg1[1], arg1[2]);
printf("%p: %c %c %c\n", arg2, arg2[0], arg2[1], arg2[2]);
printf("%p: %c %c %c\n", arg3, arg3[0], arg3[1], arg3[2]);
}
Rápido:
let input0: String? = "Zero"
let input1: String? = "One"
let input2: String? = "Two"
let input3: String? = "Three"
multiString(input0, input1, input2, input3)
Resulta em:
0x101003170: T h r
0x101003170: T h r
0x101003170: T h r
0x101003170: T h r
Parece que há um erro no modo como o Swift lida com vários argumentos.